2024-阿里云(第二套)-已改编-三语言题解

💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历

👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸

✨ 笔试合集传送们 -> 🧷学长刷题笔记

🍒 本专栏已收集 140+ 套题 🍄 题面描述等均已改编,如果和你实际看到的题面描述不一样请理解,做法和题目本质基本不变。

🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力 💞

alt

🎊 01.最短等价子串

问题描述

K 小姐接到了一个字符串处理的任务。给定一个长度为 的小写字母字符串 ,定义字符串的权值为相邻两个字符相同的对数。例如,字符串 aaabbc 的权值为 3。

现在,K 小姐需要在字符串 中找到一个长度最短的子串,使得该子串的权值恰好等于 。你能帮助她完成这个任务吗?

输入格式

第一行包含两个正整数 ,分别表示字符串 的长度和目标权值。

第二行包含一个长度为 的字符串 ,仅由小写字母组成。

输出格式

输出一个整数,表示满足条件的最短子串的长度。如果不存在这样的子串,则输出 -1。

样例输入

6 2
aaabbc

样例输出

3

数据范围

题解

本题可以使用双指针算法求解。我们用两个指针 分别表示当前子串的起点和终点。初始时,两个指针都指向字符串的起点。

我们不断地向右移动指针 ,直到当前子串的权值大于等于 。此时,我们尝试向右移动指针 ,缩小当前子串的长度,直到子串的权值恰好等于 。在这个过程中,我们记录下满足条件的最短子串长度。

重复这个过程,直到指针 到达字符串的末尾。最终得到的最短子串长度即为答案。

参考代码

  • Python
n, k = map(int, input().split())
s = input()

res = 0
ans = n + 1
i = 0
j = 1

while i < n:
    if i > 0 and s[i] == s[i - 1]:
        res -= 1
    
    while j < n and res < k:
        if s[j] == s[j - 1]:
            res += 1
        j += 1
    
    if res == k:
        ans = min(ans, j - i)
    
    i += 1

print(ans if ans != n + 1 else -1)
  • Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        String s = sc.next();
        
        int res = 0;
        int ans = n + 1;
        int i = 0;
        int j = 1;
        
        while (i < n) {
            if (i > 0 && s.charAt(i) == s.charAt(i - 1)) {
                res--;
            }
            
            while (j < n && res < k) {
                if (s.charAt(j) == s.charAt(j - 1)) {
                    res++;
                }
                j++;
            }
            
            if (res == k) {
                ans = Math.min(ans, j - i);
            }
            
            i++;
        }
        
        System.out.println(ans == n + 1 ? -1 : ans);
    }
}
  • Cpp
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main() {
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    
    int res = 0;
    int ans = n + 1;
    int i = 0;
    int j = 1;
    
    while (i < n) {
        if (i > 0 && s[i] == s[i - 1]) {
            res--;
        }
        
        while (j < n && res < k) {
            if (s[j] == s[j - 1]) {
                res++;
            }
            j++;
        }
        
        if (res == k) {
            ans = min(ans, j - i);
        }
        
        i++;
    }
    
    cout << (ans == n + 1 ? -1 : ans) << endl;
    
    return 0;
}

🎀 02.完美排列对

问题描述

K 小姐是一位数学爱好者,她正在研究排列的性质。给定一个长度为 的整数数组 ,K 小姐希望构造两个长度为 的排列 ,满足以下条件:

  1. 对于任意 ,都有
  2. 对于任意 ,都有

你能帮助 K 小姐找到这样的排列对吗?

注:排列是指一个长度为 的数组,其中 每个元素恰好出现一次。

输入格式

第一行包含一个正整数 ,表示数组 的长度。

第二行包含 个整数,表示数组 的元素,相邻两个整数之间用单个空格隔开。

输出格式

如果不存在满足条件的排列对,则输出一行,包含一个整数

否则输出两行,第一行包含 个整数,表示排列 ;第二行包含 个整数,表示排列 。相邻两个整数之间用单个空格隔开。如果存在多组解,输出任意一组即可。

样例输入

3
2 2 0

样例输出

1 3 2
3 1 2

数据范围

题解

根据题目条件,可以得到 的关系:

由条件 1 可知, 的和是固定的,都等于 。因此,可以预处理出所有可能的 对,并按照 的值进行分组。

接下来,将输入的数组 排序,然后与预处理得到的 的值进行比较。如果两个数组排序后不相同,说明无解,直接输出

如果两个数组排序后相同,则按照 数组的顺序,依次从对应的 分组中取出一对值,即可得到满足条件的排列

时间复杂度为 ,空间复杂度为

参考代码

  • Python
from collections import defaultdict

n = int(input())
a = list(map(int, input().split()))
b = a[:]
c = [abs(i - (n - 1 - i)) for i in range(n)]
mp = defaultdict(list)
for i in range(n):
    mp[c[i]].append((i, n - 1 - i))

b.sort()
c.sort()

if b != c:
    print(-1)
else:
    p = [0] * n
    q = [0] * n
    for i in range(n):
        x, y = mp[a[i]].pop()
        p[i] = x + 1
        q[i] = y + 1
    print(*p)
    print(*q)
  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        int[] b = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
            b[i] = a[

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

本专栏短期内不再更新,请勿继续订阅

全部评论

相关推荐

码农索隆:7*24,随时待命,这是去🇷🇺打仗去了啊
点赞 评论 收藏
分享
06-23 11:28
门头沟学院 Java
牛客91966197...:也有可能是点拒绝的时候自动弹的话术
点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
仁者伍敌:实习生要工作经验,工作要实习经验
点赞 评论 收藏
分享
评论
1
4
分享

创作者周榜

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