[leetCode]1297. 子串的最大出现次数

在这里插入图片描述

枚举法

由于minSizemaxSize都小于26,所以可以枚举minSizemaxSize之间的字符串,对于起始位置i和结束位置j的字符串,使用一个集合存放不同的字符。枚举每个字符时将其加入集合,如果集合的大小小于maxLetters并且并且字符串的长度在 minSizemaxSize 之间,那么我们就找到了一个满足条件的字符串。
我们使用一个无序映射(HashMap)存放所有满足条件的字符串。对于无序映射中的每个键值对,键表示字符串,值表示该字符串出现的次数。在枚举完所有的字符串后,无序映射中出现次数最多的那个字符串即为答案。

class Solution {
    public int maxFreq(String s, int maxLetters, int minSize, int maxSize) {
        int n = s.length();
        Map<String, Integer> occ = new HashMap<>();
        int ans = 0;
        for (int i = 0; i < n; i++) {
            Set<Character> exist = new HashSet<>();
            StringBuffer strbuf = new StringBuffer();
            for (int j = i; j < Math.min(n, i + maxSize); j++) {
                char c = s.charAt(j);
                exist.add(c);
                if (exist.size() > maxLetters)
                    break;
                strbuf.append(c);
                if (j - i + 1 >= minSize) {
                    String substr = strbuf.toString();
                    if (occ.get(substr) == null) {
                        occ.put(substr, 1);
                    }else {
                        occ.put(substr, occ.get(substr) + 1);
                    }
                    ans = Math.max(ans, occ.get(strbuf.toString()));
                }
            }
        }
        return ans;
    }
}

可行性优化

假设字符串 T 在给定的字符串 S 中出现的次数为 k,那么 T 的任意一个子串出现的次数至少也为 k,即 T 的任意一个子串在 S 中出现的次数不会少于 T 本身。这样我们就可以断定,在所有满足条件且出现次数最多的的字符串中,一定有一个的长度恰好为 minSize。

class Solution {
    public int maxFreq(String s, int maxLetters, int minSize, int maxSize) {
        int n = s.length();
        Map<String, Integer> occ = new HashMap<>();
        int ans = 0;
        for (int i = 0; i < n - minSize + 1; i++) {
            HashSet<Character> exist = new HashSet<>();
            for (int j = i; j < i + minSize; j++) {
                char c = s.charAt(j);
                exist.add(c);
            }
            if (exist.size() > maxLetters)
                continue;
            String cur = s.substring(i, i + minSize);
            if (occ.get(cur) == null) {
                occ.put(cur, 1);
            } else {
                occ.put(cur, occ.get(cur) + 1);
            }
            ans = Math.max(ans, occ.get(cur));
        }
        return ans;
    }
}
posted @ 2020-10-11 20:44  消灭猕猴桃  阅读(103)  评论(0编辑  收藏  举报