#P3037. 连续字母长度(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 146
            Accepted: 53
            Difficulty: 6
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>双指针          
 
连续字母长度(100分)
思路:双指针+排序
本题其实就是统计连续相同字母出现的最大长度,其实就是LeetCode的一道原题,
不太熟悉的可以参考这道题:3. 无重复字符的最长子串 - 力扣(LeetCode)
这道题面试也喜欢考,因为是双指针的经典题,使双指针去统计连续相同字母出现的最大长度之后,用一个哈希表或者一个数组记录,最终按照题目要求降序排列,输出第k多字母的次数
JavaScript代码
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
let s = '';
let k = 0;
rl.on('line', (line) => {
    if (!s) {
        s = line.trim();
    } else if (!k) {
        k = parseInt(line);
        processInput(s, k);
        rl.close();
    }
});
function processInput(s, k) {
    const cnts = Array(26).fill(0);
    const n = s.length;
    for (let i = 0; i < n; i++) {
        let j = i;
        while (j < n && s[j] === s[i]) j++;
        const c = s[i].charCodeAt(0) - 'A'.charCodeAt(0);
        cnts[c] = Math.max(cnts[c], j - i);
        i = j - 1;
    }
    cnts.sort((a, b) => b - a);
    if (k > 26 || cnts[k - 1] === 0) {
        console.log("-1");
    } else {
        console.log(cnts[k - 1]);
    }
}
C++代码
#include<bits/stdc++.h>
using namespace std;
int main(){
    string s;
    int k;
    cin>>s;
    cin>>k;
    vector<int>cnts(26,0);  //统计A~Z连续出现的最大次数
    int n=s.size();
    for(int i=0;i<n;i++){
        int j=i;
        while(j<n&&s[j]==s[i])j++;  //使用双指针找到连续出现的子串
        int c=s[i]-'A';
        cnts[c]=max(cnts[c],j-i);
        i=j-1;
    }
    sort(cnts.begin(),cnts.end(),greater<int>{});  //降序排列 找第k大
    if(k>26||cnts[k-1]==0)puts("-1");
    else cout<<cnts[k-1]<<endl;
    return 0;
}
Python代码
s = input()
k = int(input())
cnts = [0] * 26  # 统计A~Z连续出现的最大次数
n = len(s)
i=0
while i<n:
    j = i
    while j < n and s[j] == s[i]:  # 使用双指针找到连续出现的子串
        j += 1
    c = ord(s[i]) - ord('A')
    cnts[c] = max(cnts[c], j - i)
    i = j
cnts.sort(reverse=True)  # 降序排列 找第k大
if k > 26 or cnts[k - 1] == 0:
    print("-1")
else:
    print(cnts[k - 1])
Java代码
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        int k = scanner.nextInt();
        Integer[] cnts = new Integer[26];
        Arrays.fill(cnts, 0);
        int n = s.length();
        for (int i = 0; i < n; i++) {
            int j = i;
            while (j < n && s.charAt(j) == s.charAt(i)) j++;
            int c = s.charAt(i) - 'A';
            cnts[c] = Math.max(cnts[c], j - i);
            i = j - 1;
        }
        Arrays.sort(cnts, Collections.reverseOrder());
        if (k > 26 || cnts[k - 1] == 0) System.out.println("-1");
        else System.out.println(cnts[k - 1]);
    }
}
        题目描述
给定一个字符串,只包含大写字母,求在包含同一字母的子串中,长度第 k 长的子串的长度,相同字母只取最长的那个子串。
输入描述
第一行有一个字符串(1<长度≤100000),只包含大写字母 第二行为 k 的值
输出描述
输出连续出现次数第 k 多的字母的次数,当第k多的字母的次数不存在时,请输出-1
样例
输入
AAAAHHHBBCDHHHH
3
输出
2
说明
同一字母连续出现的最多的是 A 和 H ,四次 第二多的是 H,3 次,但是 H 已经存在 4 个连续的,故不考虑下个最长子串是 BB,所以最终答案应该输出2.
样例2
输入
AABAAA
2
输出
1
说明:同一字母连续出现的最多的是 A,三次, 第二多的还是 A,两次,但A已经存在最大连续次数三次 故不考虑; 下个最长子串是 B,所以输出 1。
样例3
输入
ABC
4
输出
-1
说明:只含有 3 个包含同一字母的子串,小于 k,输出 −1。
样例4
输入
ABC
2
输出
1
说明:三个子串长度均为1,所以此时 k=1,k=2,k=3 这三种情况均输出 1。特此说明,避免歧义。