leetCode 76. Minimum Window Substring

本文介绍了一种在字符串S中查找包含字符串T所有字符的最短子串的方法,使用双指针技术和计数器来实现O(n)的时间复杂度。通过不断调整窗口边界来定位最小子串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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).

For example,
S = “ADOBECODEBANC”
T = “ABC”
Minimum window is “BANC”.

Note:
If there is no such window in S that covers all characters in T, return the empty string “”.

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

找到s中最短的包含t中所有字符的子串。
思路:
两个标志位start、end,先将end右移,找到最左边的符合条件的子串
然后尝试将start右移,在满足条件的情况下找到最小的串
然后每次将end右移一位,如果不是t中字符,再右移;如果是t中字符,尝试将start右移
用一个数组维护每个字符出现的次数,并用count保存当前最小距离

 public static String minWindow(String s, String t) {
         if(s==null)return null;
         if(t==null||t.equals(""))return "";

         int []A = new int[128];
         int [] S = new int[128];
         int count=0;
         for(int i=0;i<t.length();i++){
             A[t.charAt(i)]++;
             count++;
         }
         int count2=0;
         for(int i=0;i<s.length();i++){

             if(S[s.charAt(i)]<A[s.charAt(i)]){
                 S[s.charAt(i)]++;
                 count2++;
             }
             else if(A[s.charAt(i)]>0){
                 S[s.charAt(i)]++;
             }
             if(count2==count)break;

         }
         if(count2<count)return "";
         count2=0;
        String res="";
        S = new int [128];
         int l=0;
         int r = 0;
         //先找到第一个合适的子串
         while(r<s.length()){
             char c= s.charAt(r);  
             if(S[c]<A[c]){
                 S[c]++;
                 count2++;
             }
             else if(A[c]!=0)
                 S[c]++;
             if(count2==count)
                 break;
             r++;
         }
         res = s.substring(l,r+1);
        System.out.println(res);
         int ll=l,rr=r;
         //看l能不能右移
         while(l<r){
             char c= s.charAt(l); 
             if(A[c]==0){//无关字符,直接移
                 l++;
                 if(r-l<rr-ll){
                     res = s.substring(l,r+1);
                     rr=r;
                     ll=l;
                 }
                // System.out.println(s.substring(l,r+1));
             }
             else if(S[c]>A[c]){//相关字符,计数-1
                 l++;
                 S[c]--;
                 if(r-l<rr-ll){
                     res = s.substring(l,r+1);
                     rr=r;
                     ll=l;
                 }
                 //System.out.println(s.substring(l,r+1));
             }
             else break;
         }
         //每次把r往右移一步,看l能不能右移
         r++;
         while(r<s.length()){
             char c= s.charAt(r);  
            if(A[c]>0){//找到一个符合条件的字符
                S[c]++;
                //看l能不能右移
                 while(l<r){
                     c= s.charAt(l); 
                     if(A[c]==0){//无关字符,直接移
                         l++;
                         if(r-l<rr-ll){
                             res = s.substring(l,r+1);
                             rr=r;
                             ll=l;
                         }
                        // System.out.println(s.substring(l,r+1));
                     }
                     else if(S[c]>A[c]){//相关字符,计数-1
                         l++;
                         S[c]--;
                         if(r-l<rr-ll){
                             res = s.substring(l,r+1);
                             rr=r;
                             ll=l;
                         }
                         //System.out.println(s.substring(l,r+1));
                     }
                     else break;
                 }
            }
            r++;
         }

             return res;

        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值