【算法】day3 滑动窗口
总结了一个规律:滑动窗口基本上,跟子串、子数组有关。
1、无重复字符的最长字串
题目:3. 无重复字符的最长子串 - 力扣(LeetCode)
思路:
代码:
class Solution {public int lengthOfLongestSubstring(String s) {// 字符串转字符数组char[] chars = s.toCharArray();int left = 0, right = 0;int max_len = 0;int[] hash = new int[128]; // 英文字母、数字、空格while(right < chars.length) {hash[chars[right]]++; // 进窗口while(hash[chars[right]] > 1) {hash[chars[left++]]--; // 出窗口}max_len = Math.max(max_len, right - left + 1); // 更新结果right++;}return max_len;}
}
2、最大连续 1 的个数
题目:1004. 最大连续1的个数 III - 力扣(LeetCode)
思路:最多反转 k 个 0,找到连续 1 的最长长度。相当于,找到一个最多包含 k 个 0 且最长的子数组。
代码:
class Solution {public int longestOnes(int[] nums, int k) {int left = 0, right = 0;int max_len = 0;int count = 0;while(right < nums.length) {if(nums[right] == 0) count++; // 进窗口while(count > k) {// 出窗口if(nums[left] == 0) count--;left++;}max_len = Math.max(max_len, right - left + 1); // 更新结果right++;}return max_len;}
}
3、将 x 减到 0 的最小操作数
题目:1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)
思路:两边删除最少的数,这些数达到 x。换个思路,找到最长的连续子数组,这些数的和刚好达到 target = sum - x。
代码:
class Solution {public int minOperations(int[] nums, int x) {// 找最长连续子数组,使之和恰好为 sum-xint sum = 0;int n = nums.length;for(int i = 0; i < n; i++) sum += nums[i]; // 求数组和int target = sum - x; // 恰好为 targetint max_len = -1; // 返回结果if(target < 0) return max_len; // 数组凑不齐 xint left = 0, right = 0;int tmp = 0; // 当前子数组和while(right < n) {tmp += nums[right]; // 进窗口while(tmp > target) {tmp -= nums[left++]; // 出窗口}if(tmp == target) {max_len = Math.max(max_len, right-left+1); // 更新结果}right++;}if(max_len == -1) return max_len;return n - max_len; // 最少操作数}
}