zoukankan      html  css  js  c++  java
  • 76. Minimum Window Substring

    最后更新

    一刷
    08-Jan-2017

    昨天Amazon group面结束,刚回家。
    国内以前喜欢的女生结婚了,嘿嘿...好开心呀~~

    image

    这次面试感觉自己的做法完爆别人,比什么2 greedy好多了= = 总之表现比想象的好,最后一面的面试官真是聪明得一逼,我的思路稍微说她就明白,跪了,这也太出色了。 我只能说A家对于背题党直接OA拿VIDEO或者OFFER确实水,但是有实力的也有,比如给我面试的这个印度姐姐,屌屌屌。

    总之希望自己能过能过。

    开始准备Google吧。

    言归正传。

    一长一短2个String

    在长的String里找最短的substring,使得substring包含所有短string的字符。
    ('a'在短字符串里出现2次,substring里也要出现2次才行)

    2 pointers来做的,固定左边,右边往右找,直到substring满足要求。 在往右的过程中,我们可能添加了很多不必要元素:
    要满足abc
    我们在ab baba cba里找,找到C的时候,添加了baba这段没用的,这个时候尝试左边缩进。

    比较通过2个int[256],一个是需要的字符数,一个是现有的。

    Time: O(n)
    Space: O(1)

    public class Solution {
        public String minWindow(String s, String t) {
            if (s.length() < t.length()) return "";
            int[] need = new int[256];
            int[] count = new int[256];
            
            for (char c : t.toCharArray()) {
                need[c]++;
            }
            
            int right = 0;
            String res = "";
            int minLength = Integer.MAX_VALUE;
            
            for (int left = 0; left < s.length(); left++) {
                while (right < s.length() && !contains(need, count)) {
                    count[s.charAt(right++)] ++;
                }
                
                if (right - left < minLength && contains(need, count)) {
    
                    minLength = right - left;
                    res = s.substring(left, right);
                }
                count[s.charAt(left)] --;
            }
            
            return res;
        }
        
        public boolean contains(int[] need, int[] count) {
            for (int i = 0; i < 256; i++) {
                if (need[i] > count[i]) {
                    return false;
                }
            }
            return true;
        }
    }
    

    方法二:

    也是2 pointers,和一的做法差不多,唯一不同的就是判断是否包含的方法。

    方法一是通过比较int[256]来判断是否包含所有character,这里有个别的方法。

    比如短string是abcde,那么总共需要5个字符才能满足。但也不是随便5个字符就能满足,只有某些字符才能满足。
    比如:
    一开始是abcde,需要5个才能满足,而a,b,c,d,e其中任何一个都是有效字符。
    假如我们substring中已经有了a和c,需要bde,此时的有效字符就变成了b,d,e,读到b,d,e才可以让需要数字++

    同理,缩进也要判断,比如substring里有3个A,缩进最左边缩小了1个A,那么当前需要的元素数量是不变的,因为我们还有2个A可以使用,相反如果缩掉了B,而我们substring里没有B了,总共需要的元素数量就要++

    if (--chars[s.charAt(right++)] >= 0) {
                        validRead ++;
                    }
    

    这个说的是,substring读取一个,然后判断是否是有效读取,把那些-- ++之类的给展开就一目了然了,后面的+ + --一样 ,展开再看。

    public class Solution {
        public String minWindow(String s, String t) {
            if (s.length() == 0 || s.length() < t.length()) return "";
            
            String res = "";
            int minLength = Integer.MAX_VALUE;
            
            int[] chars = new int[256];
            for (char c : t.toCharArray()) {
                chars[c] ++;
            }
            int need = t.length();
            int validRead = 0;
            int right = 0;
            for (int left = 0; left < s.length(); left ++) {
                while (right < s.length() && validRead < need) {
                    if (--chars[s.charAt(right++)] >= 0) {
                        validRead ++;
                    }
                }
                
                if (validRead >= need && right - left < minLength) {
                    minLength = right - left;
                    res = s.substring(left, right);
                }
                
                if (++chars[s.charAt(left)] > 0) validRead --;   
            }
            
            return res;
        }
    }
    

    方法二是因为后面的题要用到这个办法。

  • 相关阅读:
    搜索引擎常用技巧
    WinRaR去广告弹窗
    逆向破解之160个CrackMe —— 003
    逆向破解之160个CrackMe —— 002
    逆向破解之160个CrackMe —— 001(下)
    逆向破解之160个CrackMe —— 001(中)
    逆向破解之160个CrackMe —— 001(上)
    VMWare虚拟机无法开启,显示模块“Disk”启动失败解决办法
    uefi+gpt重装系统提示需要安装到gpt分区盘解决办法
    neg与sbb指令的结合使用
  • 原文地址:https://www.cnblogs.com/reboot329/p/6263861.html
Copyright © 2011-2022 走看看