找到字符串中所有字母异位词
题目给出两个字符串words和compare,在words中查找包含字符数量和compare相同的字字符串起始下标。
public List<Integer> findAnagrams(String s, String p) {
List<Integer> res = new ArrayList<>();
int[] words = new int[26];
int[] compare = new int[26];
for (int i = 0; i < p.length(); i++) {
compare[p.charAt(i) - 'a']++;
}
int left = 0;
for (int right = 0; right < s.length(); right++) {
int cur = s.charAt(right) - 'a';
words[cur]++;
while (words[cur] > compare[cur]) {
words[s.charAt(left) - 'a']--;
left++;
}
if (right - left + 1 == p.length()) {
res.add(left);
}
}
return res;
}
看似子串匹配,实际就是查找有相同字符数量的子串。
所以将compare字符串所包含字符记录,在words字符串用滑动窗口不断记录包含的字符值,直到相同即可。
①记录compare包含的字符串
②滑动窗口遍历words字符串
此处注意细节:用字符ASCII码作为下标,每次在words数组内记录增加时,当前字符计数小于compare数组时,不用处理;但当大于时,可以思考例如当滑动窗口内A数量为3个,而compare内A只有2个,那么不将滑动窗口内多余的A去除掉,不可能找到符合结果,故此情况需要将滑动窗口开始缩小,将左侧字符逐个除去,知道滑动窗口内A数量减为2
③最后执行判断,通过上述处理,到这里要么长度不符合compare字符串,长度符合情况下必然符合所需条件,所以当长度符合直接记录窗口左边界即可。
乘积小于 K 的子数组
在给定数据中,取到的数乘积小于上限值即可记录。
public int numSubarrayProductLessThanK(int[] nums, int k) {
if (k <= 1) {
return 0;
}
int left = 0;
int mul = 1;
int ans = 0;
for (int right = 0; right < nums.length; right++) {
mul *= nums[right];
while (mul >= k) {
mul /= nums[left];
left++;
}
ans += right - left + 1;
}
return ans;
}
依旧左右边界划分窗口进行遍历,右边界扩充时,记录乘值,当值超过则左边界收缩。
经过处理到最后一步,在结果上加窗口大小即可。
长度最小的子数组
在给定数组中查找和值>=目标值的组合,并且要求筛选出包含元素最少的组合。
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int sum = 0;
int ans = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target) {
ans = Math.min(ans, right - left + 1);
sum -= nums[left];
left++;
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
窗口遍历,右边界值持续加给sum记录;当结果超过目标值,记录当前窗口大小,与先前记录取小值,再左边界收缩,减去其值。