巨硬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必须好好刷一下才行。