Leetcode刷题 2021.02.02
Leetcode424 替换后的最长重复字符
给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。
注意:字符串长度 和 k 不会超过 10^4。
正常的滑动窗口题,其实对滑动窗口一直掌握的不是很好。经常会出现凭感觉写,然后边界各种调试的情况,要好好整理一下了。
class Solution {
public int characterReplacement(String s, int k) {
if (s == null || s.length() == 0) return 0;
char[] arr = s.toCharArray();
int i = 0, res = 0, n = arr.length, max = 0;
//因为都是大写字母,可以用一个长度26的数组保存字符出现的频率
int[] map = new int[26];
for(int j = 0; j < n; j++){
//先扩大右边窗口
map[arr[j] - 'A']++;
max = Math.max(max, map[arr[j] - 'A']);
//满足特定条件,需要缩小左窗口,这里的条件就是窗口之间的长度要大于k + 窗口之间出现频率最高的字符
while (j - i + 1 - max > k){
map[s.charAt(i) - 'A']--;
i++;
}
//更新全局的最大值
res = Math.max(res, j - i + 1);
}
return res;
}
}
Leetcode1306 跳跃游戏 III
这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。
请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处。
注意,不管是什么情况下,你都无法跳到数组之外。
理解了题目意思以后发现就是很基础的搜索提,BFS或者DFS都可以,这里用DFS。
class Solution {
boolean[] isVisited;
public boolean canReach(int[] arr, int start) {
isVisited = new boolean[arr.length];
return helper(arr, start);
}
private boolean helper(int[] arr, int index){
if (index < 0 || index >= arr.length || isVisited[index]) return false;
if (arr[index] == 0) return true;
isVisited[index] = true;
//有一个找到了就返回true
if (helper(arr, index + arr[index])) return true;
if (helper(arr, index - arr[index])) return true;
return false;
}
}
Leetcode1343 大小为 K 且平均值大于等于阈值的子数组数目
给你一个整数数组 arr 和两个整数 k 和 threshold 。
请你返回长度为 k 且平均值大于等于 threshold 的子数组数目。
一开始以为是要前缀和来做,后来发现数组的大小是固定的,那就基本没有难度了,就是遍历就行了。话说今天的中等题都出奇的简单。(lll¬ω¬)
class Solution {
public int numOfSubarrays(int[] arr, int k, int threshold) {
int n = arr.length;
if (n < k) return 0;
int sum = 0;
//先算一下前k - 1个值的和
for(int i = 0; i < k - 1; i++){
sum += arr[i];
}
int res = 0, i = 0;
for(int j = k - 1; j < n; j++){
sum += arr[j];
//然后遍历看看平均值受否大于阈值就行了,这里也可以不用除法,用乘法,算是一个小优化吧。
if ((double)(sum) / k >= threshold){
res++;
}
sum -= arr[i];
i++;
}
return res;
}
}