LeetCode 395.Longest Substring with At Least K Repeating Characters(至少有K个重复字符的最长子串) 分治/滑动窗口/medium


1.Description

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


2.Example

输入:s = "aaabb", k = 3
输出:3
解释:最长子串为 "aaa" ,其中 'a' 重复了 3 次。

输入:s = "ababbc", k = 2
输出:5
解释:最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。

3.Solution

2.滑动窗口

直接在字符串s上使用滑动窗口是不行的,根据一个窗口内包含几个不同的字母在s上进行滑动窗口才行。
1.右端点往右移动必然会导致字符类型数量增加(或不变)
2.左端点往右移动必然会导致字符类型数量减少(或不变)

    public int longestSubstring(String s, int k) {
    
    
    	int max = 0;
    	int[] chs = new int[26];
    	for(int t=1;t<=26;t++) {
    
    
    		//将chs数组归零
    		for(int i=0;i<26;i++) {
    
    
    			chs[i] = 0;
    		}
    		
    		//less代表有多少个出现次数小于k的字母,tot代表一共有多少个不同的字母
    		for(int i=0,j=0,less=0,tot=0;j<s.length();j++) {
    
    
    			int ch = s.charAt(j)-'a';
    			chs[ch]++;
    			//如果加一之后是1的话,说明进来一个新的字母,less++,tot++
    			if(chs[ch]==1) {
    
    
    				less++;
    				tot++;
    			}
    			//加一之后是k的话,说明出现次数等于k了,less--
    			if(chs[ch]==k) {
    
    
    				less--;
    			}
    			//j往后移动一位,如果从右边加进来了一个新的没出现过的字母的话,tot就大于t了,需要从左边开始去掉一种字母,使tot等于t
    			while(tot>t) {
    
    
    				int c = s.charAt(i++)-'a';//c保存i位置的字母,然后i++
    				chs[c]--;
    				if(chs[c]==0) {
    
    
    					less--;
    					tot--;
    				}
    				if(chs[c]==k-1) {
    
    
    					less++;
    				}
    			}
    			
    			if(less==0) {
    
    
    				max = Math.max(max, j-i+1);
    			}
    		}
    	}
    	return max;
    }

猜你喜欢

转载自blog.csdn.net/weixin_45736160/article/details/114179980