望着时间滴答滴答的流过,我不曾改变过 . . .

leetcode 395. Longest Substring with At Least K Repeating Characters(高质量题)

只能说还是太菜,抄的网上大神的做法:
idea:

  1. mask 的每一位代表该位字母够不够k次,够k次为0,不够为1
  2. 对于每一位将其视为起点,遍历至末尾,找到其最大满足子串T的下标max_idx,之后从max_idx+1开始遍历。

代码如下:

    public int longestSubstring(String s, int k) {
        if (k == 1) return s.length();
        int res = 0, i = 0, n = s.length();
        while (i + k <= n){
            int[] m = new int[26];
            int mask = 0, max_idx = i;
            for (int j = i; j < n; j ++){
                int t = s.charAt(j) - 'a';
                m[t]++;
                if (m[t] < k) mask |= (1 << t);
                else mask &= (~(1 << t));
                if (mask == 0){
                    res = Math.max(res, j - i + 1);
                    max_idx = j;
                }
            }
            i = max_idx + 1;
        }
        return res;
    }

下面一种做法的思路是:把串的小于k的字符当做间隔,直到这个串的每一个字符都大于等于k为止。
(一开始有这个思路,没写出来- - )

    public int helper(String s, int k, int left, int right){
        int len = right - left + 1;
        if (len <= 0)   return 0;
        int i, j, maxlen = 0;
        int[] m = new int[26];
        for (i = left; i <= right; i++)
            m[s.charAt(i) - 'a']++;
        for(i = left, j = left; i <= right; i++){
            if (m[s.charAt(i) - 'a'] < k){
                maxlen = Math.max(maxlen, helper(s, k, j, i - 1));
                j = i + 1;
            }
        }
        if (j == left)  return len;
        else return Math.max(maxlen, helper(s, k, j, i - 1));
    }
    
    
    public int longestSubstring(String s, int k) {
        return helper(s, k, 0, s.length() - 1);
    }

还有滑动窗口的做法,接下来更新。

posted @ 2019-04-27 16:01  whyaza  阅读(160)  评论(0编辑  收藏  举报