[LeetCode] 395. Longest Substring with At Least K Repeating Characters

Given a string s and an integer k, return the length of the longest substring of s such that the frequency of each character in this substring is greater than or equal to k.

Example 1:

Input: s = "aaabb", k = 3
Output: 3
Explanation: The longest substring is "aaa", as 'a' is repeated 3 times.

Example 2:

Input: s = "ababbc", k = 2
Output: 5
Explanation: The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.

Constraints:

  • 1 <= s.length <= 104
  • s consists of only lowercase English letters.
  • 1 <= k <= 105

至少有 K 个重复字符的最长子串。

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-substring-with-at-least-k-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

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

这道题我提供一个滑动窗口的思路。首先暴力解就是以一个 O(n^2) 的复杂度去遍历input字符串,看看字符串中是否存在一个 [s.charAt(j), s.charAt(i)] 的子串满足题意。这个做法会超时。这道题还有分治的思路,但是我个人觉得不是很好想所以这里不列出了。

这里我们把题目要求拆分一下。既然题目说了只有小写字母(这里好像是不太对,因为用数组统计的时候如果数组长度只创建成26是会越界的),那么我们可以从 1 到 26 去试探。这里我们试探的是找一个子串,其中包含了一个,两个,三个或者。。26 个不同字符,每个字符出现次数不少于 K。这样一来我们就可以把题目转化成类似 159 和 340 那样的做法了。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public int longestSubstring(String s, int k) {
 3         int res = 0;
 4         // 试探input字符串中是否能找到一个最长的字符串,存在有numUniqueTarget个不同字符
 5         // 我们这里是从1 - 26一个个去试探
 6         for (int numUniqueTarget = 1; numUniqueTarget <= 26; numUniqueTarget++) {
 7             res = Math.max(res, helper(s, k, numUniqueTarget));
 8         }
 9         return res;
10     }
11 
12     // sliding window模板
13     private int helper(String s, int k, int i) {
14         int[] map = new int[256];
15         int start = 0;
16         int end = 0;
17         int res = Integer.MIN_VALUE;
18         // 子串内unique的字母个数
19         int counter = 0;
20         // 出现次数不少于K的字母个数
21         int numNoLessThanK = 0;
22         while (end < s.length()) {
23             char c1 = s.charAt(end);
24             if (map[c1]++ == 0) {
25                 counter++;
26             }
27             if (map[c1] == k) {
28                 numNoLessThanK++;
29             }
30             end++;
31 
32             while (counter > i) {
33                 char c2 = s.charAt(start);
34                 if (map[c2]-- == k) {
35                     numNoLessThanK--;
36                 }
37                 if (map[c2] == 0) {
38                     counter--;
39                 }
40                 start++;
41             }
42 
43             if (counter == numNoLessThanK) {
44                 res = Math.max(res, end - start);
45             }
46         }
47         return res;
48     }
49 }

 

sliding window相关题目

LeetCode 题目总结

posted @ 2020-11-27 17:19  CNoodle  阅读(349)  评论(0编辑  收藏  举报