美团笔试 美团开发笔试 0809

笔试时间:2025年8月9日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:字符串min-15

称一个字符串为「完全不协调」,当且仅当:对于任意一种字母,其在字符串中仅有大写或仅有小写形式;对于任意一种字母(不分大小写),其都在字符串中出现过。现在,给定一个长度为 ( n )、仅由大小写字母构成的字符串 ( s )。你需要求解使其变为「完全不协调」需要的最少操作轮数 ( x )。其中,每一轮操作从以下两个方法中选择一个执行:方法一:任选一个字母(大写或小写),将其插入到字符串的任意位置(包括开头和末尾)。方法二:选择一个位于字符串中的字符,将其删除。然而,小美对数字并不感兴趣,她想知道:通过 ( x ) 轮操作能得到的字典序最小的「完全不协调」字符串是什么?【名词解释】 从字符串的第一个字符开始逐个比较,直至发现第一个不同的位置,比较这个位置字符的 ASCII 码,ASCII 码较小(‘A’ < ‘B’ … < ‘Z’ < ‘a’ < … < ‘z’)的字符串字典序也较小;如果比较到其中一个字符串的结尾时依旧全部相同,则较短的字符串字典序更小。

输入描述

每个测试文件均包含多组测试数据。第一行输入一个整数 ( T )(( 1 \le T \le 10^5 ))代表数据组数,每组测试数据描述如下: 第一行输入一个整数 ( n )(( 1 \le n \le 10^5 )),表示原字符串长度; 第二行输入一个长度为 ( n ) 的字符串 ( s ),仅由大小写字母构成。 除此之外,保证单个测试文件的 ( n ) 之和不超过 ( 10^5 )。

输出描述

对于每一组测试数据,新起一行。输出一个字符串,表示 ( x ) 轮操作能得到的字典序最小的「完全不协调」字符串。

样例输入

5

26

abcdefGHIjklmnopqrstuvwxyY

8

CAECGEHG

10

MZbMwEyYdI

20

DTLCOUegMDByFWUrPwBp

19

LKGkheSppLQSsAImtll

样例输出

ZabcdefGHIjklmnopqrstuvwxY

BCADECFGEHGIJKLMNOPQRSTUVWXYZ

ACFGHJKLMNOPQRSTUVXZbMwEYdI

ADHIJKNQSTLCOUVXZegMDByFUrPwB

BCDFGJNORUVWXYZkheSppQSAImtll

说明:对于第一组测试数据,删除了 ( y ) 并在字符串首增加了 ( Z )。

参考题解

统计字母出现情况:首先统计字符串中每个字母的出现情况(大小写分开统计),并确定哪些字母已经存在(无论大小写)。 确定缺失字母:找出所有缺失的字母(即26个字母中未出现的字母)。 处理现有字母的大小写统一:对于每个已经存在的字母,统一成大写或小写。为了使字典序最小,优先选择小写字母,因为小写字母的ASCII码比大写字母大,但若该字母的大写形式在字符串中已经存在,则必须统一成大写。 插入缺失字母:将缺失的字母插入到字符串中。为了使字典序最小,插入的字母应尽可能放在前面,特别是大写字母(因为大写字母的ASCII码较小)。具体来说,插入的大写字母应放在比它大的字符前面,而小写字母应放在合适的位置以保持字典序最小。

C++:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;

string solve(string s) {
    // 统计每个字母的大小写出现次数
    vector<int> upper(26, 0), lower(26, 0);
    
    for (char c : s) {
        if (c >= 'A' && c <= 'Z') {
            upper[c - 'A']++;
        } else {
            lower[c - 'a']++;
        }
    }
    
    // 决定每个字母使用大写还是小写
    vector<bool> useUpper(26);
    string result = "";
    
    for (int i = 0; i < 26; i++) {
        if (upper[i] == 0 && lower[i] == 0) {
            // 字母未出现,需要添加,优先使用大写(字典序更小)
            useUpper[i] = true;
        } else if (upper[i] > 0 && lower[i] > 0) {
            // 同时有大小写,保留数量多的
            if (upper[i] >= lower[i]) {
                useUpper[i] = true;
            } else {
                useUpper[i] = false;
            }
        } else {
            // 只有一种形式,保留现有的
            useUpper[i] = (upper[i] > 0);
        }
    }
    
    // 构建结果字符串
    // 先添加原字符串中需要保留的字符
    for (char c : s) {
        int idx;
        bool isUpper = (c >= 'A' && c <= 'Z');
        
        if (isUpper) {
            idx = c - 'A';
            if (useUpper[idx]) {
                result += c;
            }
        } else {
            idx = c - 'a';
            if (!useUpper[idx]) {
                result += c;
            }
        }
    }
    
    // 添加缺失的字母
    for (int i = 0; i < 26; i++) {
        if (upper[i] == 0 && lower[i] == 0) {
            result += (char)('A' + i);
        }
    }
    
    // 排序以获得字典序最小
    sort(result.begin(), result.end());
    
    return result;
}

int main() {
    int T;
    cin >> T;
    
    while (T--) {
        int n;
        string s;
        cin >> n >> s;
        cout << solve(s) << endl;
    }
    
    return 0;
}

Java:

import java.util.*;
import java.io.*;

public class Solution {
    
    public static String solve(String s) {
        // 统计每个字母的大小写出现次数
        int[] upper = new int[26];
        int[] lower = new int[26];
        
        for (char c : s.toCharArray()) {
            if (c >= 'A' && c <= 'Z') {
                upper[c - 'A']++;
            } else {
                lower[c - 'a']++;
            }
        }
        
        // 决定每个字母使用大写还是小写
        boolean[] useUpper = new boolean[26];
        StringBuilder result = new StringBuilder();
        
        for (int i = 0; i < 26; i++) {
            if (upper[i] == 0 && lower[i] == 0) {
                // 字母未出现,需要添加,优先使用大写
                useUpper[i] = true;
            } else if (upper[i] > 0 && lower[i] > 0) {
                // 同时有大小写,保留数量多的
                if (upper[i] >= lower[i]) {
                    useUpper[i] = true;
                } else {
                    useUpper[i] = false;
                }
            } else {
                // 只有一种形式,保留现有的
                useUpper[i] = (upper[i] > 0);
            }
        }
        
        // 构建结果字符串
        // 先添加原字符串中需要保留的字符
        for (char c : s.toCharArray()) {
            int idx;
            boolean isUpper = (c >= 'A' && c <= 'Z');
            
            if (isUpper) {
                idx = c - 'A';
                if (useUpper[idx]) {
                    result.append(c);
                }
            } else {
                idx = c - 'a';
                if (!useUpper[idx]) {
                    result.append(c);
                }
            }
        }
        
        // 添加缺失的字母
        for (int i = 0; i < 26; i++) {
            if (upper[i] == 0 && lower[i] == 0) {
                result.append((char)('A' + i));
      

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

2025 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论
佬,啥会投递的简历呀?投递简历之后的那个周末就会收到笔试邮件吗?
点赞 回复 分享
发布于 08-18 19:25 北京

相关推荐

08-09 12:59
郑州大学 Java
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
08-09 12:00
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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