209.长度最小的子数组

解法一:使用暴力枚举

但是及其容易超时

int minSubArrayLen(int target, int* nums, int numsSize) {
    int mintargetsize = 0;
    for(int i =0;i < numsSize;i++)
    {
      int targetsize = 0;
      int sum = 0;
      int j = i;
      while(sum <target && j <numsSize)
      {
         sum += nums[j];
         j++;
         targetsize++;
      }
      if(sum >= target)
    {
      if(mintargetsize == 0)
      {
        mintargetsize = targetsize;
      }
      else if(targetsize < mintargetsize)
      {
        mintargetsize = targetsize;
      }
    }
    }
    return mintargetsize;
}

解法二:利用单调性,使用同向双指针来优化

所以,当我们在暴力解法中发现有利用单调性时就可以使用滑动窗口算法

在上面我们很容易注意到,当len为一个确定值时,如果我们直接拿len这个区间向右移动,当这个区间内的数不满足条件时,我们不做出改变,当我们发现len内不需要这么多数就能满足条件时,我们就可以缩小窗口,之后继续向右移动

逻辑在进窗口,判断,出窗口,更新结果之间进行移动

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n = nums.size(),sum = 0,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;
    }
};

3.无重复字符的最长子串

解法一:依旧暴力枚举

解法二:利用规律使用滑动动窗口解决问题

例:deabcabca

设置right指针和left指针,当第一次遇到重复字符时,left在cab处,此时第一个a在eab处,此时两个重复字符之间的距离是小于等于最大字符的长度的,就代表没有必要进行两个a之间的遍历,假如right指针不在a的话,也没有必要进行right之后,left之前的遍历,因为无论如何一定会小于最大值

1进窗口 ------让字符进入哈希表

2.判断---------窗口内出现重复字符

出窗口  -----------从窗口中删除该字符

 更新结果

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int hash[128] = { 0 };//使用数组模拟哈希表

        int right = 0,left = 0,len = 0 , n = s.size();
        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;
    }
};

1004.最大连续1的个数III

算法原理:

转化:找出最长子数组,0的个数不超过k个

方法一:暴力枚举+zero计数器

方法二:使用滑动窗口来解决问题

1.right = 0 ,left = 0

2.进入窗口     :如果是1,无视      如果是0,计数器+1

3.判断          : zero > k

出窗口以及更新结果问题

class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int ret = 0;
        for(int left = 0,right = 0,zero = 0;right <nums.size();right++)
        {
            if(nums[right] == 0)
            {
                zero++;
            }
            while(zero > k)
            if(nums[left++] == 0) zero--;
            ret = max(ret,right-left+1);
        }
        return ret;
    }
};

更多推荐