巨硬8.27最后一次笔试

巨硬=微 软, 为防止被和谐!
巨硬公司的梗来自于网友为了调侃微软,因为微软叫微软,微”对应“巨”,“软”对“硬”,这就是巨硬公司的由来。
1. 求字符串S中所有字母均为偶数个的最长子字符串长度。字符串范围1-1E5,全为小写字母。
输入:一个字符串
输出:所有字母均为偶数个的最长子字符串长
例子1:"bdaaadadb",返回6
例子2:"abacb",返回0
例子3:"zthzth",返回6
————————————————————————————————————————————
(LC1371变种)
思路:由于题目的字符串范围较大,我们必须想出O(N)的解法,暴力法不可取。
可以采用掩码的方式,用掩码的每一位记录:
- 位为0,表明该字母出现的次数是偶数
- 位为1,表明该字母出现的次数是奇数
用哈希表记录每个掩码对应的位置。
我们依次遍历字符串S,设当前位置为i,字符为c,我们在掩码mask中对应c的位置异或1. 然后看哈希表有没有当前的掩码:
- 有,说明hashmap[mask]对应的位置idx,对应所有字符均为偶数个的子字符串长度为(i + 1 - idx),同时更新result
- 否, 则将(mask, i + 1)加入哈希表。
返回result即为所有字母均为偶数个的最长子字符串长度。
class Solution {
    public int solution1(String s) {
        Map<Integer, Integer> maskHashMap = new HashMap<>();
        maskHashMap.put(0, 0);
        int mask = 0;
        int result = 0;
        for (int i = 0, len = s.length(); i < len; ++i) {
            mask ^= 1 << (s.charAt(i) - 'a');
            int idx = maskHashMap.getOrDefault(mask, -1);
            if (idx != -1) {
                result = Math.max(result, i + 1 - idx);
            }
            else {
                maskHashMap.put(i + 1, mask);
            }
        }
        return result;
    }
}
2. 找数轴上一个最大的点的集合,该集合任意两个点距离都被M的整除。
输入:一个点的坐标数组和M
输出:最大的集合大小
例子1:{-3,-2,1,0,8,7,1 },M = 4,输出4
例子2:{7,1,11,8,4,10},M = 8,输出1

————————————————————————————————————————————
基本思路是,先将数组排序,然后遍历数组每个元素x,我们用一个哈希表保存每个数的mod( = ((x%M)+M)%M)值,对于同一个集合的元素,它们的mod一定是相同的。
我们查找哈希表,如果没有对应的mod,则将(mod, 1)加入到哈希表;否则将(mod, v + 1)加入到哈希表。
最后返回的是哈希表最大的值,如果哈希表为空,则返回1.

另外我们需要分析M的取值范围,负数,正数和0.
M为正数和负数的情况相同,对M取绝对值即可。当M为0的时候,就不能对x取模,直接将x作为mod加入到哈希表,进行上述类似的判断。
public int Solution2(int[] A, int M) {
        Map<Integer, Integer> freq = new HashMap<>();
        if (M == 0) {
            for (int x : A) {
                freq.compute(x, (k, v) -> {
                    if (v == null) {
                        return 1;
                    }
                    else {
                        return v + 1;
                    }
                });
            }
        }
        else {
            M = Math.abs(M);
            for (int x : A) {
                int mod = ((x % M) + M) % M;
                freq.compute(mod, (k, v) -> {
                    if (v == null) {
                        return 1;
                    }
                    else {
                        return v + 1;
                    }
                });
            }
        }
        return freq.isEmpty() ? 0 : freq.values().stream().max(Comparator.naturalOrder()).get();
}

3. 给定两个相同大小的数组A,B,从每个下标在A,B对应元素选一个合并为新数组C,要求C中的最小不存在正整数最小。N∈[1,1E5];
输入:数组A,B
输出:C的最小不存在整数
例子1:A=[1,2,4,3], B=[1,3,2,3],返回2
例子2:A=[3,2,1,6,5],B=[4,2,1,3,3],返回3
例子3:A=[1,2],B=[1,2],返回3
———————————————————————————————————————————
LC41
贪心算法,每次选择A,B对应元素较大的那个,然后加入到集合set中,找到set中最小不存在整数即可。
public int Solution3(int[] A, int[] B) {
    Set<Integer> set = new HashSet<>();
    for (int i = 0; i < A.length; ++i) {
        set.add(Math.max(A[i], B[i]));
    }
    for (int i = 1; i <= A.length; ++i) {
        if (!set.contains(i)) {
            return i;
        }
    }
    return A.length + 1;
}
总之,题目基本是LC中等难度题,如果想进微软,LC必须好好刷一下才行。

#微软笔试#
全部评论
例子1:{-3,-2,1,0,8,7,1 },M = 4,为啥是输出4?
点赞 回复 分享
发布于 2022-10-05 12:21 美国
最后一题的贪心策略有问题,举例A=[1,2,3,4], B=[1,1,1,1], 按照贪心策略C=[1,2,3,4],最小不存在证书是5,而事实上C=[1,1,1,1],最小可以取到2
点赞 回复 分享
发布于 2022-09-08 18:10 浙江
楼主都做出来了,强呀
点赞 回复 分享
发布于 2022-08-31 20:37 陕西

相关推荐

嵌入式求职之路:可以看我经验😂,https://www.nowcoder.com/share/jump/73221730841876945
点赞 评论 收藏
分享
评论
2
2
分享

创作者周榜

更多
牛客网
牛客企业服务