0320 java 滑动窗口

209

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn’t one, return 0 instead.

Example:

Input: s = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: the subarray [4,3] has the minimal length under the problem constraint.

Follow up:

If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).

j和i都是在同时往前走,而且j不回退

public class Solution{
  public int minimumSize(int[] nums,int s){
    int j=0,i=0;
    int sum=0;
    int ans=Integer.MAX_VALUE;
    for(i=0;i<nums.length;i++){
      while(j<nums.length&&sum<s){
        sum+=nums[j];
        j++
      }
      if(sum>=s){
        ans=Math.min(ans,j-i);
      }
      sum-=nums[i];
    }
    if(ans==Integer.MAX_VALUE)
      ans=-1;
    return ans;
  }
}


class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        int count = 0;
        for(int i=0, j=0, sum=0; i<nums.length||sum>=s;) {
            if (sum>=s) {
                int tempCount = i-j;
                if (count>tempCount || count==0) count = tempCount;
                sum-=nums[j++];
            } else {
                sum+=nums[i++];
            }
        }
        return count;
    }
}

[LeetCode] 76. Minimum Window Substring 最小窗口子串

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

Example:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"

Note:

  • If there is no such window in S that covers all characters in T, return the empty string “”.
  • If there is such window, you are guaranteed that there will always be only one unique minimum window in S.

https://www.cnblogs.com/grandyang/p/4340948.html

先遍历左窗口 计数 然后看右窗口

统计好T串中字母的个数了之后,开始遍历S串,对于S中的每个遍历到的字母,都在 HashMap 中的映射值减1,如果减1后的映射值仍大于等于0,说明当前遍历到的字母是T串中的字母,使用一个计数器 cnt,使其自增1。

当 cnt 和T串字母个数相等时,说明此时的窗口已经包含了T串中的所有字母,此时更新一个 minLen 和结果 res,这里的 minLen 是一个全局变量,用来记录出现过的包含T串所有字母的最短的子串的长度,结果 res 就是这个最短的子串。

然后开始收缩左边界,由于遍历的时候,对映射值减了1,所以此时去除字母的时候,就要把减去的1加回来,此时如果加1后的值大于0了,说明此时少了一个T中的字母,那么 cnt 值就要减1了,然后移动左边界 left。你可能会疑问,对于不在T串中的字母的映射值也这么加呀减呀的,真的大丈夫(带胶布)吗?其实没啥事,因为对于不在T串中的字母,减1后,变-1,cnt 不会增加,之后收缩左边界的时候,映射值加1后为0,cnt 也不会减少,所以并没有什么影响啦,下面是具体的步骤啦:

  • 先扫描一遍T,把对应的字符及其出现的次数存到 HashMap 中。

  • 然后开始遍历S,就把遍历到的字母对应的 HashMap 中的 value 减一,如果减1后仍大于等于0,cnt 自增1。

  • 如果 cnt 等于T串长度时,开始循环,纪录一个字串并更新最小字串值。然后将子窗口的左边界向右移,如果某个移除掉的字母是T串中不可缺少的字母,那么 cnt 自减1,表示此时T串并没有完全匹配。

 class Solution {
    public String minWindow(String s, String t) {
            int[] letterCnt = new int[128];
            int left = 0, cnt = 0, minLeft = -1, minLen = Integer.MAX_VALUE;
            for (char c : t.toCharArray()) letterCnt[c]++;
            for (int right = 0; right < s.length(); right++) {
                if(--letterCnt[s.charAt(right)] >= 0) cnt++;
                while(cnt == t.length()) {
                    if (minLen > right - left + 1) {
                        minLeft = left;
                        minLen = right - left + 1;
                    }
                //某个移除掉的字母是T串中不可缺少的字母,那么 cnt 自减1,表示此时T串并没有完全匹配
                    if (++letterCnt[s.charAt(left++)] > 0) cnt--;
                }
            }
            return minLeft == -1 ? "" : s.substring(minLeft, minLen + minLeft); 
        }
    }







1. Longest Substring Without Repeating Characters

    public class Solution{
      public int lengthOfLongestSubstring(String s){
        int[] map=new int[256];
        int i=0;
        int j=0;
        int ans=0;
        for(i=0;i<s.length();i++){
          while(j<s.length()&&map[s.charAt(j)]==0){
            map[s.charAt(j)]=1;
            ans=Math.max(ans,j-i+1);
            j++;
          }
          map[s.charAt(i)]=0;//因为要向前移动,把它剔除
        }
        return ans;
      }
    }



leetcode

      public int lengthOfLongestSubstring(String s) {
            int i=0, j=0, best=0;
            int[] count = new int[128];
            while (i< s.length()) {
                if (++count[s.charAt(i++)] == 2)
    			    while (--count[s.charAt(j++)] != 1);
                best = Math.max(best, i-j);
            }
            return best;
        }






Description

中文English

Given a string S, find the length of the longest substring T that contains at most k distinct characters.

Have you met this question in a real interview?  Yes

Problem Correction

Example

Example 1:

    Input: S = "eceba" and k = 3
    Output: 4
    Explanation: T = "eceb"
    

Example 2:

    Input: S = "WORLD" and k = 4
    Output: 4
    Explanation: T = "WORL" or "ORLD"
    

1.首先 numdistinct =0 如果前面的char[letter]=0 ++

1. 还是要继续 不是说停止就行了     k  向右滑动左窗口  =0 numdist--
2. maxlen=hi-lo+1
3. 我觉得他这个没有简化 - -count[s.charAt(hi)]==0  

    public int lengthOfLongestSubstringKDistinct(String s, int k) {
        int[] charset = new int[128]; // assume ASCII
        int maxLen = 0;
        for (int lo = 0, hi = 0, numDistinct = 0; hi < s.length(); hi++) {
            char letter = s.charAt(hi);
            if (charset[letter] == 0) numDistinct++;
            charset[letter]++;
            
            if (numDistinct > k) {
                letter = s.charAt(lo++);
                charset[letter]--;
                if (charset[letter] == 0) numDistinct--;
            }
            
            maxLen = hi - lo + 1;
        }
        return maxLen;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值