zoukankan      html  css  js  c++  java
  • leetcode至少有K个字母的最长子串

     1. 至少有K个字母的最长子串

    题目描述:给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不少于 k 。返回这一子串的长度。

    算法思路:题目要求子串中每个字母的个数都要大于k,可以先统计字符串中每个字母出现的频率,如果存在某个字母a在整个字符串中出现的频率小于k,但是满足条件的子串绝对不可能包含字母a,因此可以用字母a将字符串分割成几个子串,对子串继续上述的判断方式,直到不存在这样的字母或者字符串长度为0。自此,我们将一个大问题分割成了几个小问题,可以使用递归的方式解决。递归的返回就是满足条件的子串长度,递归结束条件:字符串长度为0或者字符串中所有字母的出现频率都大于等于k。

        public int longestSubstring(String s, int k) {
            return longestSubstring(s, k, 0, s.length() - 1);
        }
    
        public int longestSubstring(String s, int k, int start, int end) {
            if (end - start + 1 < k) {
                return 0;
            }
            int[] total = new int[26];
            // 统计字符串中每个字母个数, 找出小于k个的字母
            for (int i = start; i <= end; i++) {
                total[s.charAt(i) - 'a']++;
            }
            int longestLen = 0;
            int left = start;
            for (int i = start; i <= end; i++) {
                // 字母在字符串中出现频率小于k, 需要切割子串, 继续递归判断
                if (total[s.charAt(i) - 'a'] < k) {
                    longestLen = Math.max(longestLen, longestSubstring(s, k, left, i - 1));
                    left = i + 1;
                }
            }
            // 字符串被切割过, 需要处理切割后的最后一段
            if(left != start) {
                return Math.max(longestLen, longestSubstring(s, k, left, end));
            }
            // 字符串没有被切割过, 满足至少k个重复字符条件
            return end - start + 1;
        }
  • 相关阅读:
    面向对象七大基本原则
    JS面向对象的七大基本原则(里氏替换/依赖倒置)
    JS面向对象的七大基本原则(单一/开闭)
    flex均匀布局
    Vue在IDEA的简约安装
    事务及数据表设计
    关于序列化与反序列化
    SQL查询关键字用法
    IO流
    cookie与session
  • 原文地址:https://www.cnblogs.com/catpainter/p/14558131.html
Copyright © 2011-2022 走看看