圖解leetcode —— 395. 至少有K個重複字符的最長子串

前言:

每道題附帶動態示意圖,提供java、python兩種語言答案,力求提供leetcode最優解。html

描述:

找到給定字符串(由小寫字符組成)中的最長子串 T , 要求 T 中的每一字符出現次數都很多於 k 。輸出 T 的長度。java

示例 1:

輸入:
s = "aaabb", k = 3python

輸出:
3數組

最長子串爲 "aaa" ,其中 'a' 重複了 3 次。spa


示例 2:

輸入:
s = "ababbc", k = 2code

輸出:
5htm

最長子串爲 "ababb" ,其中 'a' 重複了 2 次, 'b' 重複了 3 次。blog

思路:

這道題能夠用滑動窗口+分治的方法進行解答。leetcode

java:

class Solution { /** * 計算最長重複子串長度. * * @param s 字符串 * @param k 重複次數 * @return 長度 */
    public int longestSubstring(String s, int k) { int len = s.length(); if (len == 0 || k > len) { return 0; } if (k < 2) { return len; } return countHandler(s.toCharArray(), k, 0, len - 1); } /** * 計算最長重複子串長度邏輯處理 * * @param chars 字符數組 * @param k 重複次數 * @param start 開始位置 * @param end 結束位置 * @return 長度 */
    private int countHandler(char[] chars, int k, int start, int end) { if (k > end - start + 1) { return 0; } // 計數器,26表明個字母
        int[] times = new int[26]; // 統計字符頻率
        for (int i = start; i <= end; i++) { ++times[chars[i] - 'a']; } // 起點、終點夾逼,去掉首位不符合條件的字符串(滑動窗口)
        while (k <= end - start + 1 && times[chars[start] - 'a'] < k) { start++; } while (k <= end - start + 1 && times[chars[end] - 'a'] < k) { end--; } if (k > end - start + 1) { return 0; } // 字符串中間存在不符合條件的字符,即以該字符串爲界,分割前子串和後字串,進行計算(分治)
        for (int i = start; i <= end; i++) { if (times[chars[i] - 'a'] < k) { return (Math.max(countHandler(chars, k, start, i - 1), countHandler(chars, k, i + 1, end))); } } return end - start + 1; } }

結果:

python3:

class Solution: def longestSubstring(self, s: str, k: int) -> int: length = len(s) if length == 0 or k > length: return 0 if k < 2: return length def countHandler(s: str, k: int, start: int, end: int) -> int: if k > end - start + 1: return 0 # 初始化數組
            times = [0 for i in range(0, 27)] for i in range(start, end + 1): times[ord(s[i]) - ord('a')] += 1
            # 起點、終點夾逼,去掉首位不符合條件的字符串(滑動窗口)
            while end - start + 1 >= k > times[ord(s[start]) - ord('a')]: start += 1
            while end - start + 1 >= k > times[ord(s[end]) - ord('a')]: end -= 1
            if k > end - start + 1: return 0 # 字符串中間存在不符合條件的字符,即以該字符串爲界,分割前子串和後字串,進行計算(分治)
            for i in range(start, end): if times[ord(s[i]) - ord('a')] < k: return max(countHandler(s, k, start, i - 1), countHandler(s, k, i + 1, end)) return end - start + 1

        return countHandler(s, k, 0, length - 1)

結果:

 

 

 

原文出處:https://www.cnblogs.com/nedulee/p/12013803.html字符串

相關文章
相關標籤/搜索