Longest Substring with At Least K Repeating Characters

Find the length of the longest substring T of a given string (consists of lowercase letters only) such that every character in T appears no less than k times.

Example 1:

Input:
s = "aaabb", k = 3

Output:
3

The longest substring is "aaa", as 'a' is repeated 3 times.

Example 2:

Input:
s = "ababbc", k = 2

Output:
5

The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.

思路:Divide and conquer; 基本原理是,先遍历整个string,并记录每个不同的character的出现次数。如果所有character出现次数都不小于k,那么说明整个string就是满足条件的longest substring,返回原string的长度即可;如果有character的出现次数小于k,假设这个character是c,因为满足条件的substring永远不会包含c,所以满足条件的substring一定是在以c为分割参考下的某个substring中。所以我们需要做的就是把c当做是split的参考,在得到的String[]中再次调用我们的method,找到最大的返回值即可。O(N^2);

class Solution {
    public int longestSubstring(String s, int k) {
        if(s == null || s.length() ==0) {
            return 0;
        }
        HashMap hashmap = new HashMap();
        for(int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            hashmap.putIfAbsent(c, 0);
            hashmap.put(c, hashmap.get(c) + 1);
        }
        
        Character less = null;
        for(Character c: hashmap.keySet()) {
            if(hashmap.get(c) < k) {
                less = c;
            }
        }
        
        int maxlen = 0;
        if(less == null) {
            return s.length();
        } else {
            String[] splits = s.split("" + less);
            for(String str: splits) {
                maxlen = Math.max(maxlen, longestSubstring(str, k));
            }
        }
        return maxlen;
    }
}

思路2:这题也可以用双指针来做;注意:

1. 阈值判断的时候,先要判断== 0,再进行++ ,先判断== k 再进行--;否则出错;

2. j move的时候,如果即将超过阈值,直接break掉,这样什么事情也没有做,而且j也停留在下一个不满足的点,直接用j - i就可以update result;

class Solution {
    public int longestSubstring(String s, int k) {
        if(s == null || s.length() == 0) {
            return 0;
        }
        int len = 0;
        for(int unique = 1; unique <= 26; unique++) {
            len = Math.max(len, getMaxUnique(s, k, unique));
        }
        return len;
    }
    
    private int getMaxUnique(String s, int k, int numOfUnique) {
        char[] ss = s.toCharArray();
        int[] scount = new int[256];
        int j = 0;
        int noLessThanK = 0;
        int unicount = 0;
        int res = 0;
        for(int i = 0; i < s.length(); i++) {
            // move j;
            while(j < s.length() && unicount <= numOfUnique) {
                if(scount[ss[j]] == 0) {
                    if(unicount == numOfUnique) {
                        break;
                    }
                    unicount++;
                }
                scount[ss[j]]++;
                if(scount[ss[j]] == k) {
                    noLessThanK++;
                }
                j++;
            }
            
            // if find, update result;
            if(unicount == numOfUnique && noLessThanK == numOfUnique) {
                res = Math.max(res, j - i);
            }
            
            // move i;
            if(scount[ss[i]] == k) {
                noLessThanK--;
            } 
            if(scount[ss[i]] == 1) {
                unicount--;
            }
            scount[ss[i]]--;
        }
        return res;
    }
}

 

你可能感兴趣的:(String,Two,pointers)