340. Longest Substring with At Most K Distinct Characters

Longest Substring with At Most K Distinct Characters
https://www.youtube.com/watch?v=RHFrVNmlyA8&t=221s

Follow up: return substring , instead of length

class Solution {
    public int lengthOfLongestSubstringKDistinct(String s, int k) {
      if(s == null || s.length() == 0){ ////// corner case 
          return 0;
      }
      if(s.length() <= k){ /////// corner case 
          return s.length();
      }
      int slow = 0;
      HashMap<Character, Integer> map = new HashMap<>();
      int maxLen = k;
      
      for(int fast = 0; fast < s.length(); fast++){
        char current = s.charAt(fast);
        Integer curCount = map.get(current);     /// could be null, so use Integer, instead of int 
        if(curCount == null){
          map.put(current, 1);
        }else{
          map.put(current, curCount + 1);
        }
        
        
        
        while(map.size() > k){
          // when the number of distince chars in the current window is bigger than k
          // we need to move the slow pointer
          char c = s.charAt(slow++);
          Integer count = map.get(c);  ///// dont recuse the count , and c as in the above code block 
          if(count == 1){
            map.remove(c);
          }else{
            map.put(c, count - 1);
          }
        }
        
        maxLen = Math.max(maxLen, fast - slow + 1);
      }
      return maxLen;
    }
}




// sliding window,
// slow fast pointer
// a hashmap<key: distinct element, value: freq>
// move fast pointer, uppdate the maxLen, the map , until 
// the size of the map is larger than k,
// then move slow pointer to the left, in order to have the number of  distinct value == k 
// when we move the slow pointer, we also need to update the map, freq - 1, if the freq 
// == 0, then remove this element from the map, 
// this happens in the while loop of "while map.size > k". once 
// the map.size is no longer bigger than k, then we can 
// move fast pointer again, repeat the above, until we reach the end of the string s 






159. Longest Substring with At Most Two Distinct Characters

 

340. Longest Substring with At Most K Distinct Characters


Input:
"aa"
1
Output:
1
Expected:
2


class Solution {
    public int lengthOfLongestSubstringKDistinct(String s, int k) {
      if(s == null || s.length() == 0){
          return 0;
      }
      if(s.length() <= k){
          return s.length();
      }
      int slow = 0;
      HashMap<Character, Integer> map = new HashMap<>();
      int maxLen = k;
      
      for(int fast = 0; fast < s.length(); fast++){
        char current = s.charAt(fast);
        Integer curCount = map.get(current);
        if(curCount == null){
          map.put(current, 1);
        }else{
          map.put(current, curCount + 1);
        }
        
        
        
        while(map.size() > k){
          // when the number of distince chars in the current window is bigger than k
          // we need to move the slow pointer
          char c = s.charAt(slow++);
          Integer count = map.get(c);
          if(count == 1){
            map.remove(c);
          }else{
            map.put(c, count - 1);
          }
        }
        
        maxLen = Math.max(maxLen, fast - slow + 1);
      }
      return maxLen;
    }
}




//// 


Input:
"aa"
1
Output:
1
Expected:
2



Wrong answer because 


 while(j < s.length()){
        if(uniqueChar <= k){
          max = Math.max(max, j - i); //////  j = 1, I = 0. After j++, j = 2 , won’t come to this whie loop 








class Solution {
    public int lengthOfLongestSubstringKDistinct(String s, int k) {
      if(s == null || s.length() == 0){
          return 0;
      }
      
      if(s.length() <= k){
        return s.length();
      }
      
      HashMap<Character, Integer> map = new HashMap<>();
      int i = 0;
      int j = 0;
      int max = Integer.MIN_VALUE;
      
      int uniqueChar = 0;
      
      while(j < s.length()){
        if(uniqueChar <= k){
          max = Math.max(max, j - i); //////  j = 1, I = 0. After j++, j = 2 , won’t come to this whie loop 
          
          char c = s.charAt(j);
          if(!map.containsKey(c)){
            uniqueChar++;
            map.put(c, 1);
          }else{
            map.put(c, map.get(c) + 1);
          }
          j++;
        }
        
        while (uniqueChar > k){
          char c = s.charAt(i);
          int freq = map.get(c);
          if(freq == 1){
            uniqueChar--;
            map.remove(c);
          }else{
            map.put(c, freq - 1);
          }
          i++;
        }
      }
      
      return max;
    }
}

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

Example 1:

Input: s = "eceba", k = 2
Output: 3
Explanation: T is "ece" which its length is 3.

Example 2:

Input: s = "aa", k = 1
Output: 2
Explanation: T is "aa" which its length is 2.

 

posted on 2018-08-09 17:44  猪猪&#128055;  阅读(119)  评论(0)    收藏  举报

导航