[leetcode]Minimum Window Substring

艰难的通过了,好多边缘条件,一开始还把realCount[S.charAt(first) - 'A']--写成了realCount[first - 'A']--,还有second到达字符串尾时,first还可以往前推的,如果total==targetTotal了。算法是参照leetcode论坛里的,两个指针。左右指针之间是满足条件的区间,判断条件是区间内的吻合值和需要的吻合值相同。注意:1.'A'小于'a';2. 两个指针的还是外面的大while和里面的两个小while。

在我的代码里是先动first再动second,看了参考的解法,先动second,到达total时再动first至可能的最右,是更简洁的解法。

参考:http://discuss.leetcode.com/questions/97/minimum-window-substring

public class Solution {
    public String minWindow(String S, String T) {
        // Start typing your Java solution below
        // DO NOT write main() function
        int targetCount[] = new int[256];
        int realCount[] = new int[256];
        int targetTotal = 0;
        for (int i = 0; i < T.length(); i++)
        {
            targetCount[T.charAt(i) - 'A']++;
            targetTotal++;
        }
        int first = 0;
        int second = 0;
        int total = 0;
        
        int start = 0;
        int end = 0;
        
        int min = Integer.MAX_VALUE;
        while (first < S.length())
        {
            if (total == targetTotal && total != 0) {  			
    			realCount[S.charAt(first) - 'A']--;
        		if (realCount[S.charAt(first) - 'A'] < targetCount[S.charAt(first) - 'A']) {
        			total--;
        		}
    			first++;
    		}       	
        	
        	// move forward first
        	while (first < S.length() && targetCount[S.charAt(first) - 'A'] == 0) {
        		first++;
        	}
        	
        	if (first >= S.length()) break;
        	
        	if (second < first) second = first;
        	
        	while (total < targetTotal && second < S.length())
        	{
        		if (targetCount[S.charAt(second) - 'A'] > 0) {
            		realCount[S.charAt(second) - 'A']++;
            		if (realCount[S.charAt(second) - 'A'] <= targetCount[S.charAt(second) - 'A']) {
            			total++;
            		}
        		}
        		second++;
        	}
        	
                if (total == targetTotal && total != 0) {
        		int dist = second - first;
    			if (dist < min) 
    			{
    			    min = dist;		
	                    start = first;
	                    end = second; 
    			}
    		}       	
       		if (second >= S.length() && total != targetTotal) break;
        }
        
        if (min == Integer.MAX_VALUE) return "";
        else
        	return S.substring(start, end);
    }

}

 Python3。其实containsMap这个方法复杂了,可以用一个cnt记录多少个字符符合要求了(mapS[char] >= mapT[char]),这样当cnt < targetCnt的时候,就可以处理。

class Solution:
    def containsMap(self, mapS, mapT): # whether s contains t
        if len(mapS) == len(mapT):
            for char in mapT:
                if char not in mapS:
                    return False
                if mapT[char] > mapS[char]:
                    return False
            return True
        
        return False
    
    def minWindow(self, s: str, t: str) -> str:
        mapT = {}
        mapS = {}
        
        for char in t:
            if not char in mapT:
                mapT[char]  = 0
            mapT[char] += 1
            
        minLen = None
        result = ''
        
        i = j = 0
        while i < len(s) and j < len(s):
            while j < len(s) and not self.containsMap(mapS, mapT): # not enough
                if s[j] in mapT: # 
                    if s[j] not in mapS:
                        mapS[s[j]] = 0
                    mapS[s[j]] += 1
                j += 1
                
            while i < len(s) and self.containsMap(mapS, mapT): # enough
                if minLen is None or j - i < minLen:
                    minLen = j - i
                    result = s[i : j]
                if s[i] in mapS:
                    mapS[s[i]] -= 1
                    if mapS[s[i]] == 0:
                        del mapS[s[i]]
                i += 1
                    
        return result

  

posted @ 2013-08-02 00:36  阿牧遥  阅读(504)  评论(0编辑  收藏  举报