【春招笔试】2025.04.19淘天春招笔试题-算法岗改编

✅ 春招备战指南 ✅

💡 学习建议:

  • 先尝试独立解题(建议用时:90分钟/套)
  • 对照解析查漏补缺
  • 配套练习题库

🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。

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

春秋招合集 -> 互联网必备刷题宝典🔗

淘天

题目一:字符交换智慧

1️⃣:将字符按ASCII码奇偶性分组

2️⃣:对每组字符分别排序

3️⃣:按照原字符串中字符的奇偶性填回排序后的字符

难度:中等

这道题目的关键在于理解ASCII码奇偶性相同的字符才能相互交换的性质。通过将字符分组排序,可以在O(n log n)的时间复杂度内得到字典序最小的字符串。

题目二:秒杀顺子查找

1️⃣:利用动态规划统计不同长度的顺子子序列

2️⃣:使用哈希表存储状态

3️⃣:从长度1到5逐步构建顺子子序列

难度:中等

这道题目结合了子序列和顺子的概念,通过巧妙的动态规划状态设计,可以高效统计满足条件的子序列数量,避免了暴力枚举所有可能的组合。

题目三:数值平衡之道

1️⃣:确定目标值为原始值的中位数

2️⃣:利用树形动态规划计算最优连通子图

3️⃣:通过后序和前序遍历,计算最小操作成本

难度:中等偏难

这道题目需要综合应用数学推导和树形动态规划,关键思路是将最小化成本问题转化为寻找最大权连通子图问题。通过巧妙的状态设计,可以在O(n)的时间复杂度内解决问题。

01. 字符交换智慧

问题描述

小柯有一个长度为 的字符串 ,该字符串仅由大小写字母构成。

她发现了一种神奇的交换规则:当两个字符的 ASCII 码差值为偶数时,它们可以被交换。具体来说,她可以进行任意次如下操作:

  • 选择两个不同的位置 ,要求按照 ASCII 表, 为偶数。
  • 交换 的值。

小柯想知道,经过任意次操作后,能得到的字典序最小的字符串是什么。

【字典序比较】:从字符串的第一个字符开始逐个比较,直到找到第一个不同的位置,通过比较这个位置字符的 ASCII 码大小得到字符串的大小,称为字典序比较。

输入格式

第一行输入一个正整数 ,表示字符串的长度。

第二行输入一个字符串 ,保证仅由大小写字母构成。

输出格式

输出一个字符串,表示可以经过操作得到的字典序最小的字符串。

样例输入

4
cfae

样例输出

afce

数据范围

  • 字符串 仅由大小写字母构成
样例 解释说明
样例1 将 'c' 和 'a' 交换,'c'(99) 和 'a'(97) 的ASCII码差为2(偶数),所以可以交换。交换后字符串变为 "afce",这是可以得到的字典序最小的字符串。

题解

这道题目要求我们通过交换字符得到字典序最小的字符串,关键是理解交换的限制条件:只有ASCII码差值为偶数的字符才能交换。

仔细分析可以发现一个重要性质:ASCII码为奇数的字符只能与ASCII码为奇数的字符交换,ASCII码为偶数的字符只能与ASCII码为偶数的字符交换。这是因为两个奇数或两个偶数的差值一定是偶数,而一个奇数和一个偶数的差值一定是奇数。

根据这个性质,我们可以将字符串中的字符分成两组:

  1. ASCII码为奇数的字符组
  2. ASCII码为偶数的字符组

在每组内,字符可以任意交换位置。因此,为了得到字典序最小的字符串,我们应该:

  1. 将奇数组的字符按升序排序
  2. 将偶数组的字符按升序排序
  3. 按照原字符串中字符的奇偶性,依次填入排序后的奇数或偶数字符

例如对于示例"cfae":

  • 'c'的ASCII码是99(奇数)
  • 'f'的ASCII码是102(偶数)
  • 'a'的ASCII码是97(奇数)
  • 'e'的ASCII码是101(奇数)

奇数组:['c', 'a', 'e'] → 排序后变成 ['a', 'c', 'e'] 偶数组:['f'] → 排序后还是 ['f']

然后按照原字符串中字符的奇偶性重构:

  • 第1个位置原来是'c'(奇数),填入'a'
  • 第2个位置原来是'f'(偶数),填入'f'
  • 第3个位置原来是'a'(奇数),填入'c'
  • 第4个位置原来是'e'(奇数),填入'e'

得到结果:"afce",这就是字典序最小的字符串。

算法的时间复杂度是 O(n log n),主要来自对两组字符的排序,空间复杂度是 O(n)。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()

# 读取输入
n = int(input())
s = input()

# 将字符分为ASCII码奇数和偶数两组
odd = []
even = []
for c in s:
    if ord(c) % 2 == 0:
        even.append(c)
    else:
        odd.append(c)

# 对两组字符分别排序
odd.sort()
even.sort()

# 构建结果字符串
res = ""
oi, ei = 0, 0
for c in s:
    if ord(c) % 2 == 0:
        # ASCII码为偶数的位置
        res += even[ei]
        ei += 1
    else:
        # ASCII码为奇数的位置
        res += odd[oi]
        oi += 1

print(res)
  • Cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    // 读取输入
    int n;
    string s;
    cin >> n >> s;
    
    // 分离奇偶ASCII码字符
    vector<char> odd, even;
    for (char ch : s) {
        if (ch % 2 == 0) {
            even.push_back(ch);
        } else {
            odd.push_back(ch);
        }
    }
    
    // 排序
    sort(odd.begin(), odd.end());
    sort(even.begin(), even.end());
    
    // 构建结果
    string ans = "";
    int o = 0, e = 0;
    for (char ch : s) {
        if (ch % 2 == 0) {
            ans += even[e++];
        } else {
            ans += odd[o++];
        }
    }
    
    cout << ans << endl;
    return 0;
}
  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // 读取输入
        int n = sc.nextInt();
        sc.nextLine(); // 消耗换行符
        String s = sc.nextLine();
        
        // 分离奇偶ASCII码字符
        List<Character> odd = new ArrayList<>();
        List<Character> even = new ArrayList<>();
        
        for (char c : s.toCharArray()) {
            if (c % 2 == 0) {
                even.add(c);
            } else {
                odd.add(c);
            }
        }
        
        // 排序
        Collections.sort(odd);
        Collections.sort(even);
        
        // 构建结果
        StringBuilder res = new StringBuilder();
        int oddIdx = 0, evenIdx = 0;
        
        for (char c : s.toCharArray()) {
            if (c % 2 == 0) {
                res.append(even.get(evenIdx++));
            } else {
                res.append(odd.get(oddIdx++));
            }
        }
        
        System.out.println(res.toString());
    }
}

02. 秒杀顺子查找

问题描述

小兰是一名热爱扑克牌的玩家。她定义一个数列是"顺子",当且仅当将该数列排序后,每个元素恰好比前一个元素大 。比如, 排序后是 ,相邻元素之差为 ,所以这是一个"顺子"。而 排序后是 ,包含重复元素,不满足条件,所以不是"顺子"。

现在,小兰拿到了一个长度为 的数列,她想知道这个数列中有多少个长度恰好为 的子序列可以构成"顺子"。由于答案可能很大,请将结果对 取模后输出。

【子序列定义】:从原数列中选取部分元素并保持它们在原数列中的相对顺序组成的新数列,称为原数列的子序列。例如,对于数列 是其子序列,而 不是,因为不满足相对顺序。

输入格式

第一行输入一个正整数 ,代表数列的长度。

第二行输入 个正整数 ,代表数列的元素。

输出格式

一个整数,代表顺子的数量对 取模的值。

样例输入

6
1 2 3 4 5 6

样例输出

2

样例输入

10
1 2 3 4 5 1 2 3 4 5

样例输出

32

数据范围

样例 解释说明
样例1 数列 [1,2,3,4,5,6] 中,可以构成顺子的长度为5的子序列有 [1,2,3,4,5] 和 [2,3,4,5,6],共2个
样例2 数列 [1,2,3,4,5,1,2,3,4,5] 中,有多种方式可以选取元素组成长度为5的顺子,例如可以从数列前半部分选择5个连续数,也可以从后半部分选择,还可以混合选择。计算得到共有32个满足条件的子序列

题解

这道题目要求我们计算长度为5的顺子子序列的数量。首先明确一下,顺子是指排序后相邻元素之差为1的数列,长度为5的顺子实际上就是连续的5个整数。

关键是理解:无论这5个数的初始顺序如何,只要它们组成连续的5个整数,就构成一个顺子。

一个巧妙的解法是使用动态规划,定义状态:

  • dp[1][v]:以值v结尾的长度为1的子序列个数
  • dp[2][v]:以值v结尾的长度为2的子序列个数,且这些子序列满足条件(即v前面的数等于v-1)
  • dp[3][v]:以值v结尾的长度为3的子序列个数,且满足顺子条件
  • dp[4][v]:以值v结尾的长度为4的子序列个数,且满足顺子条件
  • dp[5][v]:以值v结尾的长度为5的子序列个数,且满足顺子条件

状态转移方程为:

  1. dp[1][v] += 1(每次遇到值v,长度为1的子序列增加1个)
  2. dp[2][v] += dp[1][v-1](以v-1结尾的长度为1的子序列后面接上v,构成长度为2的子序列)
  3. dp[3][v] += dp[2][v-1](以v-1结尾的长度为2的子序列后面接上v,构成长度为3的子序列)
  4. dp[4][v] += dp[3][v-1](以此类推)
  5. dp[5][v] += dp[4][v-1](以此类推)

最终答案是所有dp[5][v]的总和。

由于数据范围较大(a_i可达10^9),我们可以使用哈希表而不是数组来存储状态,以节省空间。

例如,对于样例1 [1,2,3,4,5,6]:

  • 处理1:dp[1][1]=1
  • 处理2:dp[1][2]=1, dp[2][2]=dp[1][1]=1
  • 处理3:dp[1][3]=1, dp[2][3]=dp[1][2]=1, dp[3][3]=dp[2][2]=1
  • 处理4:dp[1][4]=1, dp[2][4]=dp[1][3]=1, dp[3][4]=dp[2][3]=1, dp[4][4]=dp[3][3]=1
  • 处理5:dp[1][5]=1, dp[2][5]=dp[1][4]=1, dp[3][5]=dp[2][4]=1, dp[4][5]=dp[3][4]=1, dp[5][5]=dp[4][4]=1
  • 处理6:dp[1][6]=1, dp[2][6]=dp[1][5]=1, dp[3][6]=dp[2][5]=1, dp[4][6]=dp[3][5]=1, dp[5][6]=dp[4][5]=1

最终答案为dp[5][5]+dp[5][6]=1+1=2。

算法的时间复杂度是O(n),空间复杂度也是O(n),可以高效处理给定的数据范围。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()

# 读取输入
n = int(input())
arr = list(map(int, input().split()))

# 初始化哈希表
MOD = 10**9 + 7
dp1 = {}  # 长度为1的子序列
dp2 = {}  # 长度为2的顺子子序列
dp3 = {}  # 长度为3的顺子子序列
dp4 = {}  # 长度为4的顺子子序列

# 动态规划过程
ans = 0
for val in arr:
    # 获取前一个值的各长度顺子数量
    c4 = dp4.get(val-1, 0)
    c3 = dp3.get(val-1, 0)
    c2 = dp2.get(val-1, 0)
    c1 = dp1.get(val-1, 0)
    
    # 累加长度为5的顺子数量
    ans = (ans + c4) % MOD
    
    # 更新状态
    dp4[val] = (dp4.get(val, 0) + c3) % MOD
    dp3[val] = (dp3.get(val, 0) + c2) % MOD
    dp2[val] = (dp2.get

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

互联网刷题笔试宝典 文章被收录于专栏

互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

全部评论

相关推荐

04-21 10:59
已编辑
哈尔滨工程大学 Java
🔍&nbsp;AI算法工程师&amp;amp;amp;银行信息技术岗1.&nbsp;面试流程概览AI工程师岗位面试通常分为以下环节:技术初筛:简历评估+线上编程题(LeetCode中等难度为主)。技术一面:围绕简历项目深挖技术细节,涉及AI模型、算法优化等。技术二面:系统设计题(如设计推荐系统、优化模型推理效率)。HR面:职业规划、团队协作、抗压能力等软实力考察。2.&nbsp;高频技术问题算法基础:手写交叉熵损失函数推导,分析其梯度;Transformer中Self-Attention的时间复杂度如何优化?项目深挖:如何解决模型过拟合问题?实际项目中如何选择评估指标?是否尝试过模型蒸馏/量化?效果如何?场景题:若用户反馈推荐系统效果下降,如何定位问题?设计一个金融风控模型,需考虑哪些特征和业务约束?3.&nbsp;算法题准备建议刷题重点:动态规划(背包问题、字符串编辑距离)、树/图遍历(DFS/BFS)、Top&nbsp;K问题。例题参考:LeetCode&nbsp;215(数组第K大元素)LeetCode&nbsp;239(滑动窗口最大值)4.&nbsp;行为面试技巧必问题:“遇到技术难题如何解决?”&nbsp;→&nbsp;STAR法则回答(情境-任务-行动-结果)。“团队合作出现分歧如何处理?”&nbsp;→&nbsp;强调沟通优先级与数据驱动决策。反问环节:可问团队技术栈、业务发展方向,体现主动性。🚀&nbsp;招商银行第9季数字金融训练营:AI工程师的黄金跳板!🔥&nbsp;核心亮点抢先看零门槛福利:包吃住+报销路费,全程无开销!直通Offer:表现优异者直接拿2026校招提前批Offer,特别优秀者获PLUS&nbsp;Offer(薪资/职级加成)。实战为王:依托招行真实业务场景,接触亿级用户数据与金融级AI模型。📌&nbsp;赛道选择建议AI工程师赛道:熟悉大模型、多模态技术者优先,可挑战模型调优、工程化部署等任务。AI数据科学家赛道:需精通Python/SQL、统计建模,侧重风控/营销数据分析。AI产品经理赛道:考察需求分析、原型设计能力,金融场景创新是加分项。⏰&nbsp;关键时间节点截止时间:2025年4月24日工作地点:深圳(总行资源倾斜,技术氛围浓厚)🎯&nbsp;内推专属通道立即报名抢占席位&nbsp;👉&nbsp;招商银行训练营内推链接请戳这里https://cmb-recruitment-mobile.paas.cmbchina.com/positionDetail/school?publishId=19237290-CFB7-4176-A91C-444831ECCD4F&amp;amp;amp;qrCodeId=599C6E39-A7DD-4620-AC1A-30F1D63BA322&amp;amp;amp;recruitmentTypeId=670980EA-30B6-455A-93C2-5CD5258B8A36💡&nbsp;面试备战Tips技术复盘:针对简历项目准备3个以上优化延伸问题(如模型瓶颈、AB实验设计)。行业洞察:提前研究招行“金融科技”战略(如掌上生活App智能推荐),面试可结合业务谈技术方案。模拟面试:找伙伴Mock系统设计题,练习白板绘图与模块化拆解思维。🌟&nbsp;训练营与面试双重助力,提前锁定大厂Offer!立即行动,用实战经验碾压面试考场&nbsp;👊(训练营详情可以留言探讨哦~)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务