LeetCode – Minimum Window Substring (Java)

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

Java Solution

public String minWindow(String s, String t) {
    if(t.length()>s.length()) 
        return "";
    String result = "";
 
    //character counter for t
    HashMap<Character, Integer> target = new HashMap<Character, Integer>();
    for(int i=0; i<t.length(); i++){
        char c = t.charAt(i);    
        if(target.containsKey(c)){
            target.put(c,target.get(c)+1);
        }else{
            target.put(c,1);  
        }
    }
 
    // character counter for s
    HashMap<Character, Integer> map = new HashMap<Character, Integer>();
    int left = 0;
    int minLen = s.length()+1;
 
    int count = 0; // the total of mapped characters
 
    for(int i=0; i<s.length(); i++){
        char c = s.charAt(i);
 
        if(target.containsKey(c)){
            if(map.containsKey(c)){
                if(map.get(c)<target.get(c)){
                    count++;
                }
                map.put(c,map.get(c)+1);
            }else{
                map.put(c,1);
                count++;
            }
        }
 
        if(count == t.length()){
            char sc = s.charAt(left);
            while (!map.containsKey(sc) || map.get(sc) > target.get(sc)) {
                if (map.containsKey(sc) && map.get(sc) > target.get(sc))
                    map.put(sc, map.get(sc) - 1);
                left++;
                sc = s.charAt(left);
            }
 
            if (i - left + 1 < minLen) {
                result = s.substring(left, i + 1);
                minLen = i - left + 1;
            }
        }
    }
 
    return result;
}
Category >> Algorithms >> Interview  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>

  1. Nand Jha on 2015-8-7

    count == t.length()
    After doing the operation when you meet your desired count of characters in T, you need to decrease count by 1 as you are removing character one by one. AT the end when it will find the desired smallest length it would take one character out of the map and hence it should decrease that count by 1 as well.

  2. Kyle on 2015-10-5

    You’re right. 🙂

  3. gao can on 2016-2-1

    No, it doesn’t need to do it. Although it is a good idea to decrease count by 1. Then taking one character out of the map and increase left by 1.
    S = “ADOBECODEBANC”, T = “ABC”.
    Think about this case, first we find “ADOBEC” then when count == t.length(), left is A since we can not drop any of character then we move left to D and move A from map and count–. This is the method that you talk about.
    But we can keep count as 3 and without moving left, we still move i to next A,
    then it becomes “ADOBECODEBA”, here count == 3 == t.length(), but now we can move left from the first A to C, it becomes “CODEBA”.
    See, that is the reason we don’t need to decrease count by 1.

  4. Renzo on 2016-2-18
  5. Larry Okeke on 2016-3-21

    This runs in O(n log n). but the idea is easier to understand.

    count through word till you’ve gotten all the characters in your target substring, and then compare the length to last result.

    import java.util.*;

    public class shortest_window{

    public static void main(String[] args){

    String word = "ADOBECODEBANC";

    String target = "ABC";

    System.out.println(solution(word, target));

    }

    public static String solution(String word, String targ){

    if(word==null || word.length() < 1 ) return "";

    if(targ==null || targ.length() < 1) return "";

    char arr = new targ.toCharArray();

    String shortest = word;

    for(int i =0; i < word.length(); i++){

    String temp = "";

    ArrayList target = new ArrayList();

    for(Character c: arr){

    target.add((Character)c);

    }

    for(int j = i; j temp.length()) shortest = temp;

    break;

    }

    }

    }

    return shortest;

    }

    }

  6. Subodh Karwa on 2016-11-13

    The loop for
    count == t.length() can be modified to count == t.length() && map.containsKey(c)
    for more optimized checking

  7. John Smith on 2016-11-23

    The complexity of this is O(n^2) since there are n(n+1)/2 operations.

  8. Derek on 2016-12-25

    I think the complexity is O(n^2), since there are n(n+1)/2. obviously the upper bound is not 2*n, So it is not O(n). I searched online, lots of guys claim complexity is O(n^2). To me that is not right.

  9. Ahmad El-Qaoud on 2017-1-1

    Faster and easier to understand solution: (O(n))

    public static String shortestWindow(String s, String t) {
    if (s == null || s == “” || t == null || t == “”) {
    return null;
    }
    LinkedHashMap map = new LinkedHashMap();
    String shortest = null;
    for (int i = 0; i (i – map.entrySet().iterator()
    .next().getValue())) {
    shortest = s.substring(map.entrySet().iterator().next()
    .getValue(), i+1);
    }
    map.clear();
    }

    }
    return shortest;
    }

  10. Sourav_Kings on 2017-1-26

    This code FAILS for this example:

    Input string1: “this is a test string”
    Input string2: “tist”
    Output string: “t stri”

Leave a comment

*