连续字母长度 - 华为OD统一考试(D卷)

OD统一考试(D卷)

分值: 100分

题解: Java / Python / C++

华为od真题

题目描述

给定一个字符串,只包含大写字母,求在包含同一字母的子串中,长度第 k 长的子串的长度,相同字母只取最长的那个子串。

输入描述

第一行有一个字符串(1<长度≤1000001<长度≤100000),只包含大写字母 第二行为 k 的值

输出描述

输出连续出现次数第 k 多的字母的次数,当第k多的字母的次数不存在时,请输出-1

示例1

输入:
AAAAHHHBBCDHHHH
3

输出:
1

说明:
同一字母连续出现的最多的是 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。特此说明,避免歧义。

题解

解题思路:

  1. 遍历字符串,统计相同字母的连续子串的长度。
  2. 使用数组 cnt 记录每个字母最长子串的长度,其中 cnt[i] 表示字母 A + i 的最长子串长度。
  3. 使用集合 scnt 进行去重处理,记录所有不同的子串长度。
  4. 判断集合 scnt 的大小,如果小于 k,则输出 -1,表示不存在第 k 多的字母。
  5. 否则,将数组 cnt 排序,输出第 26 - k 个元素,即第 k 多的字母的最长子串长度。

Java

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

/**
 * @author code5bug
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        String s = in.next();
        int k = in.nextInt();

        // 相同字母取最长的那个子串长度
        // cnt[1] 表示 'B' 最长的子串长度
        int[] cnt = new int[26];

        int n = s.length();
        for (int i = 0; i < n; ) {
            int j = i + 1;
            while (j + 1 < n && s.charAt(j) == s.charAt(i)) j++;

            int idx = s.charAt(i) - 'A';
            cnt[idx] = Math.max(cnt[idx], j - i);

            i = j;
        }

        // 去重处理
        Set<Integer> scnt = new HashSet<>();
        for (int i = 0; i < 26; i++) {
            if (cnt[i] > 0) {
                scnt.add(cnt[i]);
            }
        }

        if (scnt.size() < k) {
            System.out.println(-1);
        } else {
            // 排序长度
            Arrays.sort(cnt);
            System.out.println(cnt[26 - k]);
        }
    }
}

Python

# 相同字母取最长的那个子串长度
# cnt[1] 表示 'B' 最长的子串长度
cnt = [0] * 26

# 输入字符串和k值
s = input()
k = int(input())

n = len(s)
i = 0
while i < n:
    j = i + 1
    while j + 1 < n and s[j] == s[i]:
        j += 1

    idx = ord(s[i]) - ord('A')
    cnt[idx] = max(cnt[idx], j - i)

    i = j

# 去重处理
scnt = set([cnt[i] for i in range(len(cnt)) if cnt[i] > 0])

if len(scnt) < k:
    print(-1)
else:
    # 排序长度
    cnt.sort()
    print(cnt[26 - k])

C++

#include <bits/stdc++.h>
using namespace std;

int main(){
    string s;
    int k;
    cin >> s;
    cin >> k;

    // 相同字母取最长的那个子串长度
    // cnt[1] 表示 'B' 最长的子串长度
    int cnt[26] = {0};

    int n = s.length();
    for(int i=0;i<n;){
        int j = i + 1;
        while(j + 1 < n && s[j] == s[i]) j++;

        int idx = s[i] - 'A';
        cnt[idx] = max(cnt[idx], j - i);

        i = j;
    }

    // 去重处理
    set<int> scnt;
    for(int i=0;i<26;i++){
        if(cnt[i] > 0) scnt.insert(cnt[i]);
    }

    if(static_cast<int>(scnt.size()) < k){
        cout << -1 << endl;
    }else{
        // 排序长度
        sort(cnt, cnt + 26);
        cout << cnt[26 - k] << endl;
    }

    return 0;
}

‍整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

#面经##秋招##华为od##华为od题库##校招#
全部评论
@在巴厘岛游泳的小苹果
点赞 回复 分享
发布于 2024-07-30 18:31 广东
面经好评,看看我的offer选择吧。
点赞 回复 分享
发布于 2024-07-26 19:23 广西

相关推荐

01-08 11:19
已编辑
深圳职业技术学院 护士
我是从大一下学期5月开始转互联网的,原因很简单,对本专业的就业薪资与前景非常不满,而我特别想赚钱,所以选了互联网,而又因为带我的师兄都是前端,所以阴差阳错就做了前端当时的梦想就是进腾讯,进腾讯,进腾讯!大一下学期学了3个月的前端的基础知识后,开始参加学校工作室的考核,当时整个暑假都没回家,跑去自习室和考研的同学坐一下,那段时间我敢说我去的比大多数人早,走的比大多数人晚,把所有的时间精力都扑在做工作室考核上面,不过结果非常遗憾,我竞争不过两个超级大神,最后进不去了(广工的anyview是我一身之痛)不过进了物理学院的软件组,有了自己的工位还有好多转码师兄的指导后,开始长达半年的实验室之旅......在这半年,我几乎没有上课,没有去哪里玩,我像一个被写了程序的机器人一样,7点半起床,去实验室学前端,一直到晚上10点&nbsp;11点。我太笨了,太笨了,学东西太慢了,coderwhy的网课看了一遍又一遍,项目代码写了一遍又一遍,红宝书也是一遍一遍的看......就这样,过完了这打了鸡血的半年,寒假也只回去十天左右,然后就到了24年的3月我开始焦虑,非常非常的焦虑与害怕,因为我开始刷牛客了,开始去网上了解各种就业信息,一大堆负面信息朝我涌来,我不知道怎么区分就全盘接收前端已死,互联网完蛋了,非科班别想了,双非别想了,没有学历就等于判了死刑......有半个月我半夜都会被吓醒,后面想到的一个破局之路就是刷实习,大量的堆实习,弥补我双非的学历,非科班的专业带来的巨大劣势于是开始转战图书馆,找了考研的人一起坐,他们什么时候去我就什么时候去,开始背八股,前端三件套,框架,工程化,算法,计算机网络......这些对我当时的我来说太多了太多了,也太难太难了,越看越焦虑,越焦虑我越不敢停下来,每天晚上都要去跑5公里来让自己平静下来就这样过了一个多月,我准备的七七八八开始投实习了,第一次面试,我整个人紧张的止不住的颤抖,喝了一杯又一杯的水,上了一次又一次的厕所,皇天不负有心人,在四月底找到了自己的第一份外包实习,很大程度地缓解了我的焦虑,回去休息了半个月五一后入职,实习了一个星期左右,感觉太难受了,工作氛围及其压抑,同事也是感觉都乱来的,而且喜欢打压我,我在写算法的时候,他们老说不用写这个,这些是大厂才要的,你又进不去大厂......&nbsp;后面我只能偷偷跑楼下写,过了小半个月我实在呆不下去就离职回学校了,第一段实习就这样结束了,而且老板不给我发工资......于是我开始在学校二次沉淀了,开始大量刷leetcode&nbsp;代码随想录&nbsp;codetop&nbsp;准备更强的项目&nbsp;更深入地背八股,于是一直学啊学啊,那个暑假就回去两个星期学车,其他时间都呆在学校的实验室里24年8月开始全面投实习,拿了古茗&nbsp;卓望数码的offer,本来打算去杭州古茗的,结果美团打电话说面试通过,阴差阳错地去了上海美团,开启了自己的第一段实习刚去没多久,还没适应那里的生活工作环境,学校传来噩耗,外出实习被抓到了,老师逼我回去,说不回去毕不了业,我当时听完电话后,整个人崩溃了,我跑去公司楼道间一直哭,我不甘心,我太不甘心了,我不甘心来之不易的实习泡汤,幸好后面申请了一门实验课重修,如愿留在上海于是就在上海美团实习了四个月,一直到了25年1月,我开始飘了,我感觉自己牛逼坏了,感觉美团平台不够高,想去更高的腾讯和字节,放弃了美团核心部门,而且高转正率的机会,选择了离职,当时还在牛客写了一篇长文于是回家休息到年后,2月多开始回学校全力准备暑期实习,一直面一直挂,直到5月份才找到字节的实习,这三个月是我最痛苦最煎熬的日子,我的自信心被不断的击碎,一直面一直挂,而身边朋友开始接连上岸,我开始怀疑自己,开始后悔当时的决定,开始觉得自己就是一个看不清自己的傻逼然后呢,4月底&nbsp;在没招了,万念俱灰的时候,字节约面试了,一点也不想复习,裸面,结果阴差阳错给我干进去了5月中开始字节的实习,虽然压力比较大,但还可以接受,平平稳稳能干了三个月,自我感觉良好,以为转正稳了,结果到八月初的时候,通知转正失败,当时天都塌了,然后开始找其他部门的机会,后面活水成功,去另一个部门实习了一个月,其实转正概率也不小,但是当时也是心比天高,以为自己牛逼坏了,所以选择离职秋招9月中开始全面秋招,结果大家也知道,秋招大溃败,各种终面挂&nbsp;hr面挂&nbsp;排序挂&nbsp;有时候也不知道为什么挂,问题也都答出来了,算法也都写出来了,但就是挂哈哈哈哈其中很多时间都是在打字节的复活赛,反复仰卧起坐,反复鞭尸,后面感觉面字节跟回家和亲戚聊天一样,他会问什么我都知道,甚至我可以抢答,面完还能聊天开点玩笑......在12月中的时候,字节又约面了,阴差阳错又到了三面,结果还给整挂了,当时确实破防的要死,然后转部门面试,本来打算拒绝的,因为实在太心累,太折磨了,但还是咬咬牙去面了,然后莫名其妙问的也就那些,三面还整了几道脑筋急转弯,本来以为又要挂了,结果过了,据说是因为我的竞争对手三面ai作弊被发现了,所以只面了她16分钟,所以就轮到我了,我也不用hr面直接审批,然后审批半天,隔天直接谈薪,hr开了个我拒绝不了的薪资,而且表达出来的意思是无论其他开多少字节都能match的意思,诚意满满回望这两年多的经历,真的是非常非常感慨,我想和大家说的是每个人都会有属于自己花期,只是时间的问题而已,努力踏实做事,终究会有回报!我也曾在这条路上迷茫、焦虑、崩溃与无助,但我做的唯一的一件事情就是,整理好心情,重新出发,坚持下去,光脚的不怕穿鞋的,拼了兄弟们!
码农索隆:我感觉兄弟你所处在环境已经算是双非中比较好的了,双非院校中很少有实验室,也鲜有师哥师姐会带着去学习,而你也很争气抓住了这次机会,一飞冲天
现在前端的就业环境真的很...
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务