intminSubArrayLen(int target, int* nums, int numsSize) { // // 1.定义左右窗口和保存的结果 // int left = 0; // int right = 0; // int ret = INT_MAX; // int sum = 0; // while(right < numsSize) // { // sum += nums[right]; // while(sum >= target) // { // ret = ret < (right - left + 1) ? ret : (right - left + 1); // 缩小窗口,可能left++还是大于目标值,所以while循环的 // sum -= nums[left++]; // 左边缩小窗口 // } // right++; // 右边扩大窗口的 // } // return ret == INT_MAX ? 0 : ret ;
int left = 0; int right = 0; int ret = INT_MAX; int sum = 0; while(right < numsSize) { sum += nums[right]; while(sum >= target) { ret = ret < (right - left + 1) ? ret : (right - left + 1); sum -= nums[left++]; }
classSolution { public: intminSubArrayLen(int target, vector<int>& nums) { // 1.定义窗口的指针。 int left = 0; int right = 0; int ret = INT_MAX; // 定义很大的值,是为了更新窗口信息的。 int sum = 0;
// 2.right到了头,数据遍历完毕了的。 while(right < nums.size()) { sum += nums[right]; // 3.进窗口,就要判断一次的。 while(sum >= target) { // 4.更新结果的 ret = min(ret, right - left + 1);
// int left = 0; // int right = 0; // int n = nums.size(); // int ret = INT_MAX; // int sum = 0; // while(right < n) // { // sum += nums[right]; // while(sum >= target) // { ret = min(ret, right - left + 1); // sum -= nums[left++]; // } // right++; // } // return ret == INT_MAX ? 0 : ret;
//[2 3 1 4] // l r >= target; // l r // 利用单调性,同向双指针,滑动窗口。 // 怎么用呢?
// 1.left = 0; right = 0; // 2.进入窗口 // 3.判断 // 出窗口 /* r 2 3 1 2 4 3 l 1.l = 0; r = 0; sum = 0; 2.进入窗口 sum = 2 3.进 sum = 5; 4.进 sum = 6; 5.进 sum = 8; 出,更新sum(这里是这道题更新结果。) len = r-l sum = 6; l++(3) 6.进 sum = 10; len = r - l; sum = 7; l++;(1) 二次判断 len = r - l; sum = 6; l++;l=(2) 7.进 */
/* 为什么是对的? 单调性: r 2 3 1 2 4 3 l l+r>=target,已经没有必要枚举后面的了的。 */
// 时间复杂度2N;N // int n = nums.size(); // int sum = 0; // int ret = INT_MAX; // for(int left = 0, right = 0; right < n; right++) // { // sum += nums[right]; // 进入窗口 // while(sum >= target) // 判断 // { // ret = min(ret, right-left+1); // 跟新结果 // sum -= nums[left++]; // 滚出窗口 // } // } // return ret == INT_MAX ? 0 : ret;
}
/* #include <vector> #include <algorithm> #include <climits> // 用于 INT_MAX using namespace std; class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { int n = nums.size(); if (n == 0) return 0; int left = 0; int right = 0; int sum = 0; int minLen = INT_MAX; // 初始化为最大整数,方便后面取最小值 // 移动 right 指针扩大窗口 while (right < n) { sum += nums[right]; // 当窗口内的和满足条件时,尝试缩小窗口 while (sum >= target) { // 更新最小长度 int currentLen = right - left + 1; minLen = min(minLen, currentLen); // 缩小窗口:减去左边的值,左指针右移 sum -= nums[left]; left++; } // 继续扩大窗口 right++; } // 如果 minLen 还是 INT_MAX,说明没找到满足条件的子数组,返回 0 return (minLen == INT_MAX) ? 0 : minLen; } }; */
for(int right = 0; right < s.size(); ++right) { left = max(left, index[s[right]] + 1);
index[s[right]] = right;
maxLen = max(maxLen, right - left + 1); }
return maxLen;
// // 1.数组模拟哈希表。 // int hash[128] = {0}; // // 2.双指针,指针变量 // int left = 0; // int right = 0; // int n = s.size(); // int ret = 0; // while(right < n) // { // // 3.进窗口, // hash[s[right]]++;
/* r abcabcbb l r abcabcbb l r abcabcbb l r abcabcbb a */ // int n = s.size(); // int left = 0; // int right = 0; // int hash[128] = {0}; // int ret = 0; // while(right < n) // { // hash[s[right]]++; // while(hash [s[right]] > 1) // >1 需要有元素,退出窗口。直到这里没有大于1.去重成功了的。 // { // hash[s[left++]]--; // 出窗口 left去重成功,则上面的s[right] < 1的。 // } // ret = max(ret, right - left + 1); // right++; // 下一个元素进入窗口的 // }
// return ret;
// 子串。子数组。都是连续的。 // 子序列是不连续的。 /* abcabcbb abc bca 1.暴力解法 abcabcbb r de a bc a bca l r de a bc a bca l r de a bc a bca l // 双指针同一个方向,就是滑动指针。 时间复杂度N */ /* 1.left right; 2.进----字符进入hash_table right++ 3.判断 窗口内出现重复字符 出 让重复的字符划出窗口,hash删除结果 4.更新 重复的时候,更新 为什么?? 滑动窗口?这是因为重复了的。 */ // int hash[128] = {0}; // 数组模拟hash // int n = s.size(); // int left = 0; // int right = 0; // int ret = 0; // while(right < n) // { // hash[s[right]]++; // while(hash[s[right]] > 1) // { // hash[s[left++]]--; // } // ret = max(ret, right-left+1); // right++; // } // return ret; // int n = s.size(); // int left = 0, right = 0; // int count[128] = {0}; // int ret = 0; // while(right < n) // { // char c = s[right]; // count[c]++;
intlongestOnes(int* nums, int numsSize, int k) { int left = 0; int right = 0; int zeros = 0; int ret = 0; for(right; right < numsSize; right++) { if(nums[right] == 0) { zeros++; }
ret = ret > (right - left + 1) ? ret : (right - left + 1); } return ret;
// int left = 0; // int right = 0; // int zeros = 0; // int ret = 0; // for(right; right < numsSize; ++right) // { // if(nums[right] == 0) // { // zeros++; // }
// while(zeros > k) // { // if(nums[left] == 0) // { // zeros--; // } // } // ret = ret > (right - left + 1) ? ret : (right - left + 1); // }
classSolution { public: intlongestOnes(vector<int>& nums, int k) { // 1.定义双指针 int left = 0; int right = 0; int n = nums.size(); int count = 0; int ret = 0;
int len =words[0].size(); // 一个单词多长 int m = words.size(); // 多少个单词
// 执行len次 for(int i = 0; i < len; i++) { unordered_map<string, int> hash2; for(int left = i, right = i, count = 0; right + len <= s.size(); right += len) { string in = s.substr(right, len); hash2[in]++; if(hash2[in] <= hash1[in]) { count++; }
if(right - left + 1 > len * m) { string out = s.substr(left, len); if(hash2[out] <= hash1[out]) count--; hash2[out]--;
left += left; }
if(count == m) { ret.push_back(left); } } }
return ret; } };
76.最小覆盖子串
给定两个字符串 s 和 t,长度分别是 m 和 n,返回 s 中的 最短窗口 子串,使得该子串包含 t 中的每一个字符(包括重复字符)。如果没有这样的子串,返回空字符串 ""。
测试用例保证答案唯一。
示例 1:
1 2 3
输入:s = "ADOBECODEBANC", t = "ABC" 输出:"BANC" 解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。
示例 2:
1 2 3
输入:s = "a", t = "a" 输出:"a" 解释:整个字符串 s 是最小覆盖子串。
示例 3:
1 2 3 4
输入: s = "a", t = "aa" 输出: "" 解释: t 中两个字符 'a' 均应包含在 s 的子串中, 因此没有符合条件的子字符串,返回空字符串。