import java.util.*; /** * NC364 至少有 K 个重复字符的最长子串 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string字符串 * @param k int整型 * @return int整型 */ public int longestSubstring (String s, int k) { return solution1(s, k); // return solution2(s, k); } /** * 滑动窗口 * @param s * @param k * @return */ private int solution1(String s, int k){ int len = s.length(); if(k == 1){ return len; } if(len < k){ return 0; } // 可能的最大窗口 int max = 0; int[] count = new int[26]; for(char ch: s.toCharArray()){ count[ch-'a']++; } for(int i=0; i<26; i++){ if(count[i] >= k){ max += count[i]; } } // 滑动窗口 for(int gap=max; gap>=k; gap--){ for(int i=0; i+gap<=len; i++){ if(isValid(s.substring(i, i+gap), k)){ return gap; } } } return 0; } /** * 子串是否合法 * @param sub * @param k * @return */ private boolean isValid(String sub, int k){ int[] count = new int[26]; for(char ch: sub.toCharArray()){ count[ch-'a']++; } for(int i=0; i<26; i++){ if(0<count[i] && count[i]<k){ return false; } } return true; } /** * 分治法 * @param s * @param k * @return */ private int solution2(String s, int k){ return divide(s, k); } /** * 递归: 分治 * @param s * @param k * @return */ private int divide(String s, int k){ int len = s.length(); if(k == 1){ return len; } if(len < k){ return 0; } HashMap<Character, Integer> map = new HashMap<>(); for(char ch: s.toCharArray()){ map.put(ch, map.getOrDefault(ch, 0)+1); } for(char ch: s.toCharArray()){ if(map.get(ch) < k){ int maxLen = 0; for(String part: s.split(String.valueOf(ch))){ maxLen = Math.max(maxLen, divide(part, k)); } return maxLen; } } return s.length(); } }