zoukankan      html  css  js  c++  java
  • [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个重复字符的最长子串。

    找到给定字符串(由小写字符组成)中的最长子串 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 题目总结

  • 相关阅读:
    Codeforces 177G2 Fibonacci Strings KMP 矩阵
    Codeforces Gym100187C Very Spacious Office 贪心 堆
    Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
    AtCoder SoundHound Inc. Programming Contest 2018 E + Graph (soundhound2018_summer_qual_e)
    BZOJ3622 已经没有什么好害怕的了 动态规划 容斥原理 组合数学
    NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分
    Codeforces 555C Case of Chocolate 其他
    NOIP2017提高组Day2T3 列队 洛谷P3960 线段树
    NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp
    NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14049253.html
Copyright © 2011-2022 走看看