1. LeetCode 3 无重复字符的最长子串
方法1:滑动窗口 + 哈希
class Solution {public int lengthOfLongestSubstring(String s) {HashSet<Character> set = new HashSet<Character>();int left = 0, ans = 0;for (int right = 0; right < s.length(); right++) {while (set.contains(s.charAt(right)))set.remove(s.charAt(left++));ans = Math.max(ans, right - left + 1);set.add(s.charAt(right));}return ans;}
}
class Solution:def lengthOfLongestSubstring(self, s: str) -> int:st = set(); left = ans = 0for right, ch in enumerate(s):while ch in st:st.remove(s[left])left += 1ans = max(ans, right - left + 1)st.add(ch)return ans
2. LeetCode 1493 删掉一个元素以后全为1的最长子数组
方法1:滑动窗口
class Solution {public int longestSubarray(int[] nums) {int left = 0, ans = 0, cnt = 0; // 标记当前 0 的个数for (int right = 0; right < nums.length; right++) {if (nums[right] == 0)cnt += 1;while (cnt > 1) {if (nums[left] == 0)cnt -= 1;left += 1;}// 保证[left , right]中只有一个 0ans = Math.max(ans, right - left + 1);}return ans - 1;}
}
class Solution:def longestSubarray(self, nums: List[int]) -> int:cnt, left, ans = 0, 0, 0for right, x in enumerate(nums):if x == 0:cnt += 1while cnt > 1:if nums[left] == 0:cnt -= 1left += 1# 保证[left, right]中只有一个 0ans = max(ans, right - left + 1)return ans - 1 # 减去其中需要删除的一个元素
方法2:思维 + 前缀和
class Solution {public int longestSubarray(int[] nums) {int n = nums.length;int[] prev = new int[n]; // 当前位置结尾前面连续 1 的个数prev[0] = nums[0]; // 初始化for (int i = 1; i < n; i++)prev[i] = nums[i] == 1 ? prev[i - 1] + 1 : 0;int[] next = new int[n]; // 当前位置结尾后面连续 1 的个数next[n - 1] = nums[n - 1]; // 初始化for (int i = n - 2; i >= 0; i--)next[i] = nums[i] == 1 ? next[i + 1] + 1 : 0;int ans = 0;for (int i = 0; i < n; i++) { // 枚举要删除的位置int prevS = i == 0 ? 0 : prev[i - 1];int nextS = i == n - 1 ? 0 : next[i + 1]; ans = Math.max(ans, prevS + nextS);}return ans;}
}
class Solution:def longestSubarray(self, nums: List[int]) -> int:n = len(nums)pre = [nums[0]] * n; nxt = [nums[n - 1]] * nfor i in range(1, n): # 初始化 pre 数组pre[i] = 0 if nums[i] == 0 else pre[i - 1] + 1for i in range(n - 2, -1, -1):nxt[i] = 0 if nums[i] == 0 else nxt[i + 1] + 1ans = 0for i in range(n):preS = 0 if i == 0 else pre[i - 1]nxtS = 0 if i == n - 1 else nxt[i + 1]ans = max(ans, preS + nxtS)return ans
3. LeetCode 2730 找到最长的半重复子字符串
方法1:滑动窗口
class Solution {public int longestSemiRepetitiveSubstring(String s) {int val = 0, left = 0, ans = 1; // 当只有一个字符时返回 1for (int right = 1; right < s.length(); right++) {if (s.charAt(right) == s.charAt(right - 1))val += 1; // 相邻重复个数加 1while (val > 1) {if(s.charAt(left) == s.charAt(left + 1))val -= 1;left += 1;}ans = Math.max(ans, right - left + 1);}return ans;}
}
class Solution:def longestSemiRepetitiveSubstring(self, s: str) -> int:cnt, left, ans = 0, 0, 1for right in range(1, len(s)):if s[right - 1] == s[right]:cnt += 1while cnt > 1:if s[left] == s[left + 1]:cnt -= 1left += 1ans = max(ans, right - left + 1)return ans
4. LeetCode 904 水果成篮
方法1:滑动窗口 + 哈希表
class Solution {public int totalFruit(int[] fruits) {// 标记区间数字出现次数HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();// left:左端点 ans:最终答案int left = 0, ans = 0;for (int right = 0; right < fruits.length; right++) {map.merge(fruits[right], 1, Integer::sum);while (map.size() > 2) {if (map.merge(fruits[left], -1, Integer::sum) == 0)map.remove(fruits[left]); left += 1;}ans = Math.max(ans, right - left + 1);} return ans;}
}
class Solution:def totalFruit(self, fruits: List[int]) -> int:cnt = Counter() # python的计数器left, ans = 0, 0for right, x in enumerate(fruits):cnt[x] += 1 # 如果不存在会自动创建while len(cnt) > 2:cnt[fruits[left]] -= 1if cnt[fruits[left]] == 0: # 需要手动删除cnt.pop(fruits[left])left += 1ans = max(ans, right - left + 1)return ans
5. LeetCode 1695 删除子数组的最大得分
方法1:滑动窗口 + 哈希表
class Solution {public int maximumUniqueSubarray(int[] nums) {HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();int left = 0, val = 0, ans = 0;for (int right = 0; right < nums.length; right++) {map.merge(nums[right], 1, Integer::sum);val += nums[right];while (map.get(nums[right]) > 1) {map.merge(nums[left], -1, Integer::sum);// 此处可以删除键值为 0 的键val -= nums[left]; left++;}ans = Math.max(ans, val);}return ans;}
}
class Solution:def maximumUniqueSubarray(self, nums: List[int]) -> int:cnt = Counter() # 统计每个数字出现的次数left, val, ans = 0, 0, 0for right, x in enumerate(nums):cnt[x] += 1; val += xwhile cnt[x] > 1:cnt[nums[left]] -= 1val -= nums[left]# 此处可以删除个数为 0 的键left += 1ans = max(ans, val)return ans
6. LeetCode 2958 最多 K 个重复元素的最长子数组
方法1:滑动窗口 + 哈希表
class Solution {public int maxSubarrayLength(int[] nums, int k) {HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();int left = 0, ans = 0;for (int right = 0; right < nums.length; right++) {map.merge(nums[right], 1, Integer::sum);while (map.get(nums[right]) > k) {map.merge(nums[left], -1, Integer::sum);// 此处可以删除键值为 0 的键left++;}ans = Math.max(ans, right - left + 1);}return ans;}
}
class Solution:def maxSubarrayLength(self, nums: List[int], k: int) -> int:cnt = Counter() # 统计每个数字出现的次数left, ans = 0, 0for right, x in enumerate(nums):cnt[x] += 1while cnt[x] > k:cnt[nums[left]] -= 1# 此处可以删除个数为 0 的键left += 1ans = max(ans, right - left + 1)return ans
7. LeetCode 1004 最大连续1的个数III
方法1:滑动窗口
class Solution {public int longestOnes(int[] nums, int k) {int cnt = 0, left = 0, ans = 0;for (int right = 0; right < nums.length; right++) {cnt += nums[right] == 0 ? 1 : 0;while (cnt > k) {cnt -= nums[left] == 0 ? 1 : 0;left += 1;}ans = Math.max(ans, right - left + 1);}return ans;}
}
class Solution:def longestOnes(self, nums: List[int], k: int) -> int:cnt, left, ans = 0, 0, 0for rigth, x in enumerate(nums):cnt += 1 if x == 0 else 0while cnt > k:cnt -= 1 if nums[left] == 0 else 0left += 1ans = max(ans, rigth - left + 1)return ans
8. LeetCode 2024 考试的最大困扰度
方法1:滑动窗口
class Solution {public int maxConsecutiveAnswers(String answerKey, int k) {return Math.max(longest(answerKey, k, 'T'), longest(answerKey, k, 'F'));}public int longest(String s, int k, char ch) {int cnt = 0, left = 0, ans = 0;for (int right = 0; right < s.length(); right++) {cnt += s.charAt(right) == ch ? 1 : 0;while (cnt > k) {cnt -= s.charAt(left) == ch ? 1 : 0;left += 1;}ans = Math.max(ans, right - left + 1);}return ans;}
}
class Solution:def maxConsecutiveAnswers(self, answerKey: str, k: int) -> int:return max(self.longest(answerKey, k, 'T'), self.longest(answerKey, k, 'F'))def longest(self, s: str, k: int, ch: str) -> int:cnt, left, ans = 0, 0, 0for rigth, x in enumerate(s):cnt += 1 if x == ch else 0while cnt > k:cnt -= 1 if s[left] == ch else 0left += 1ans = max(ans, rigth - left + 1)return ans
9.