zoukankan      html  css  js  c++  java
  • 图解leetcode —— 395. 至少有K个重复字符的最长子串

    前言:

    每道题附带动态示意图,提供java、python两种语言答案,力求提供leetcode最优解。

    描述:

    找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。

    示例 1:

    输入:
    s = "aaabb", k = 3

    输出:
    3

    最长子串为 "aaa" ,其中 'a' 重复了 3 次。


    示例 2:

    输入:
    s = "ababbc", k = 2

    输出:
    5

    最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。

    思路:

    这道题可以用滑动窗口+分治的方法进行解答。

    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)

    结果:

  • 相关阅读:
    UI自动化web端框架config.json代码
    UI自动化web端框架run.py代码
    UI自动化web端框架核心组成和目录结构
    appium环境搭建(windows-appium-android)
    官网pyse的修改版
    git安装和使用、python安装
    单例设计模式、工厂设计模式和装饰器
    AcWing 245 你能回答这些问题吗? (线段树)
    AcWing 244 谜一样的牛 (线段树)
    AcWing 239 奇偶游戏 (带权并查集 / 扩展域并查集)
  • 原文地址:https://www.cnblogs.com/nedulee/p/12013803.html
Copyright © 2011-2022 走看看