其他分享
首页 > 其他分享> > 每日一题:Leetcode 395 每个元素不少于k个的最长子串

每日一题:Leetcode 395 每个元素不少于k个的最长子串

作者:互联网

题目名:Leetcode 395 至少有 K 个重复字符的最长子串
网站:https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/
题目描述:给个字符串和一个整数k,要求最长子串长度,要求子串每个元素在子串出现次数不低于k。
思路:分片+dfs
dfs(深度优先)建议自己找资料,很重要的算法,现在知道不仅是找东西,这种字符串限定范围也可以应用,经验++。
代码:

class Solution {
    // 分割法:先看有那些字符是小于k的,最大字串一定是这些字符分割的子串
    public int longestSubstring(String s, int k) {
        int len_ = s.length();
        return dfs_cut(s,0,len_-1,k);
        // 虽然dfs,但是会随着层数的下降,更大的结果覆盖小结果,最终得到的是最大结果
    }
    private int dfs_cut(String s,int start, int end, int k){
        //统计词频
        int alphabet[]=new int[26];
        for(int i = start; i <= end ; i++){
            alphabet[s.charAt(i)-'a']++;
        }

        char split = 0;
        // 因为dfs,所以每次一个字符分割就行,不要想着开局直接分割完所有字符串
        for(int j=0 ; j<26 ; j++){
            if(alphabet[j]<k && alphabet[j]>0){
                split = (char)(j+'a');
                break;
            }
        }

        if(split == 0){
            //字符串统计出来已经不存在截断字符了,直接返回当前字串长度
            return end - start + 1;
        }

        // i 为当前字符串指针
        int i=start;
        // cur_length 为已有的最大长度记录
        int cur_length = 0;

        while(i <= end){
            // 针对 split ,这个循环讲字符串分为很多份,每份调用以此dfs,其中又有其他子字符串
            // 掠过一直的不行的字符串
            while(i<=end && s.charAt(i)==split){
                i++;
            }
            if(i > end){
                break;
            }
            // 设定新字符串的起点
            int new_start = i;
            while (i <= end && s.charAt(i)!=split){
                i++;
            }
            // 掠过无分界字符的字串,得到子串终点
            // dfs
            int length_this_time = dfs_cut(s,new_start,i-1,k);
            cur_length = Math.max(cur_length,length_this_time);
        }
        return cur_length;
    }
}

标签:子串,int,dfs,start,length,395,字符串,Leetcode
来源: https://blog.csdn.net/qq_42511414/article/details/115028971