209. 长度最小的子数组
class Solution {
// 方法 minSubArrayLen 接收一个整数 s 和一个整数数组 nums
// 返回和大于或等于 s 的最小子数组长度
public int minSubArrayLen(int s, int[] nums) {
int n = nums.length; // 获取数组的长度
// 如果数组为空,直接返回 0
if (n == 0) {
return 0;
}
// 初始化答案为最大整数,表示最小子数组的长度
int ans = Integer.MAX_VALUE;
// 初始化两个指针,分别为滑动窗口的左右边界
int start = 0, end = 0;
// 初始化当前窗口的总和
int sum = 0;
// 使用滑动窗口的方式,右边界 end 向右移动
while (end < n) {
sum += nums[end]; // 将当前元素加入总和
// 当当前窗口的和大于或等于目标值 s 时,尝试收缩窗口
while (sum >= s) {
// 更新答案为当前窗口长度的最小值
ans = Math.min(ans, end - start + 1);
sum -= nums[start]; // 从总和中减去左边界的元素
start++; // 移动左边界,缩小窗口
}
end++; // 移动右边界,扩展窗口
}
// 检查是否找到了符合条件的子数组,返回结果
return ans == Integer.MAX_VALUE ? 0 : ans; // 如果 ans 没有更新,返回 0,不然返回 ans
}
}
3. 无重复字符的最长子串
class Solution {
// 方法 lengthOfLongestSubstring 接收一个字符串 s,返回不包含重复字符的最长子串的长度
public int lengthOfLongestSubstring(String s) {
// 将字符串转换为字符数组
char[] arr = s.toCharArray();
// 创建一个集合以存储当前窗口中的字符
Set<Character> set = new HashSet<>();
// 初始化答案,表示最长子串的长度
int ans = 0;
// 使用双指针(滑动窗口)的方法
for (int left = 0, right = 0; right < arr.length; right++) {
// 当右指针指向的字符已经存在于集合中,收缩左边界
while (set.contains(arr[right])) {
// 从集合中移除左指针指向的字符
set.remove(arr[left]);
// 左指针右移,继续寻找不重复的字符
left++;
}
// 将当前右指针指向的字符加入集合
set.add(arr[right]);
// 更新答案,计算当前窗口的长度并取最大值
ans = Math.max(ans, right - left + 1);
}
// 返回最长子串的长度
return ans;
}
}