今天学习双向指针滑动窗口【基础算法精讲 03】_哔哩哔哩_bilibili
cpp
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
// 滑动窗口的核心思想是 "扩大右边界累加,满足条件时收缩左边界"
int n = nums.size();
int left = 0, right = 0;
int ans = n + 1;
int sum = 0;
for (right; right < n; right++) {
sum += nums[right];
while (sum >= target) {
ans = min(ans, right - left + 1);
sum -= nums[left];
left++;
}
}
return ans > n ? 0 : ans;
}
};
这道题当作模板背过。
713. 乘积小于 K 的子数组 - 力扣(LeetCode)
cpp
class Solution {
public:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
// 子数组内所有元素的乘积严格小于 k 的连续子数组的数目
// 边界条件:k≤1时,无满足条件的子数组(数组元素为正整数)
if (k <= 1) return 0;
int n = nums.size();
int left = 0, right = 0;
int ans = 0;
long long product = 1; // 用long long避免整数溢出
for (; right < n; right++) {
product *= nums[right]; // 右边界扩窗,累乘
// 乘积≥k时,收缩左边界直到乘积<k
while (product >= k) {
product /= nums[left];
left++;
}
// 以right为结尾的满足条件的子数组数目 = 窗口长度
ans += right - left + 1;
}
return ans;
}
};
总结
cpp
1.边界条件处理(k≤1):
题目中 nums 的元素都是正整数,所以任何子数组的乘积≥1。如果 k≤1,没有子数组能满足 "乘积严格小于 k",直接返回 0,避免后续错误计算。
2.避免整数溢出:
将product的类型从int改为long long,因为当 nums 的元素较大、数组较长时,累乘的结果会超出 int 的范围(比如 nums=[10,2,3], k=1000,累乘到 1023=60 没问题,但更长的数组会溢出)。
cpp
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int ans=0;
int left=0;int right=0;
int n=s.length();
unordered_set<char> window;
for(right;right<n;right++){
char c=s[right];
while(window.contains(c)){
window.erase(s[left]);
left++;
}
window.insert(c);
ans=max(ans,right-left+1);
}
return ans;
}
};
哈希常用
cpp
unordered_set<char> window;
window.contains(c))
window.erase(s[left]);
window.insert(c);