package com.freetymekiyan.algorithms.level.medium; /** * 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. * <p> * Example 1: * <p> * Input: * s = "aaabb", k = 3 * <p> * Output: * 3 * <p> * The longest substring is "aaa", as 'a' is repeated 3 times. * <p> * Example 2: * <p> * Input: * s = "ababbc", k = 2 * <p> * Output: * 5 * <p> * The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times. */ public class LongestSubstringwithAtLeastKRepeatingCharacters { /** * Divide and conquer. * For those characters in string which repeat less than k times, we try to divide the string into two parts: * 1) left part: from the beginning to character's left * 2) right part: from the character's right to the end * The result is the larger one of these two parts. */ public int longestSubstring(String s, int k) { return helper(s, 0, s.length(), k); } private int helper(String s, int start, int end, int k) { if (end < start) { return 0; } if (end - start < k) { // String length less than k return 0; } int[] count = new int[26]; // Character count for current string for (int i = start; i < end; i++) { count[s.charAt(i) - 'a']++; } for (int i = 0; i < 26; i++) { if (count[i] == 0) { continue; } if (count[i] < k) { for (int j = start; j < end; j++) { if (s.charAt(j) == i + 'a') { int left = helper(s, start, j, k); int right = helper(s, j + 1, end, k); return Math.max(left, right); } } } } return end - start; } }