2025.04.10-拼多多春招笔试真题

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

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

拼多多

题目一:神奇公园的福娃占卜

1️⃣:遍历字符串,统计连续'1'的最大长度

2️⃣:判断最大连续长度是否等于9

难度:简单

这道题目要求判断字符串中最长连续'1'的数量是否恰好等于9。通过一次遍历,使用计数器记录当前连续'1'的数量,并更新最大连续数量,最后判断是否等于9即可。是一道典型的字符串处理问题,时间复杂度为O(n)。

题目二:糖果店的优惠兑换计划

1️⃣:根据公式计算每位顾客的免费额度

2️⃣:判断总免费额度是否足够,不足则计算所需兑换券数量

难度:中等

这道题涉及优惠兑换规则的理解和数学计算。关键是分析出每位顾客有一个"免费额度",可以不用兑换券就能兑换一定数量的糖果。通过计算总免费额度,再根据剩余糖果数量计算所需兑换券数,可以高效解决问题。需要注意大数处理,时间复杂度为O(T)。

题目三:数字重排最大化问题

1️⃣:分析序列长度关系,简化特殊情况

2️⃣:贪心构造解,从高位到低位尝试匹配

3️⃣:必要时回溯调整前面的选择

难度:中等偏难

这道题要求将一个数字序列重排,使其尽可能大但又小于另一个给定数字。解法采用贪心策略,从高位到低位构造结果。需要处理序列长度不同的特殊情况,并在构造过程中适时回溯,是一道考验思维能力和实现技巧的问题。时间复杂度为O(n)。

题目四:优惠券最优分配问题

1️⃣:对商品和优惠券按价格/门槛排序

2️⃣:使用最大堆维护当前可用的优惠券

3️⃣:贪心选择策略,为每个商品分配减免最大的可用优惠券

难度:中等

这道题目是典型的贪心算法应用场景。通过对商品和优惠券排序,并利用优先队列(最大堆)来存储可用的优惠券,可以高效地为每个商品分配最优的优惠券。理解为什么贪心策略在这个问题中是最优的是解题的关键。时间复杂度为O((n+m)log(m))。

01. 神奇公园的福娃占卜

问题描述

小基在一个神奇的公园里发现了一条特殊的小径,小径上排列着一群可爱的福娃玩偶。这条小径有 个位置按顺序排列,每个位置最多可以放置一个福娃。小径的状态可以用一个仅包含 的字符串 来表示,其中 等于 表示第 个位置上放着福娃,等于 则表示该位置空着。

根据公园管理员的说法,如果小径上连续的福娃数量(即连续的 的数量)恰好等于 ,那么这条小径就具有神奇的力量,被认为是"幸运小径"。小基想知道眼前的小径是否是幸运的。如果是幸运小径,请输出 ,否则输出

输入格式

第一行包含一个正整数 ,代表测试数据的组数。

对于每组测试数据,分别有两行:

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

第二行包含一个仅由 组成、长度为 的字符串 ,其中 表示第 个位置是否有福娃,等于 时有,等于 时没有。

输出格式

对于每组数据,如果小径是幸运的(连续福娃数量恰好等于 ),则输出 ,否则输出

样例输入

2
9
111111111
3
110

样例输出

lucky
unlucky

数据范围

样例 解释说明
9
111111111
小径长度为9,所有位置都有福娃,形成了连续9个福娃,恰好等于9,所以是幸运小径。
3
110
小径长度为3,前两个位置有福娃,连续福娃数量为2,不等于9,所以不是幸运小径。

题解

这道题目其实非常直观,我们需要找出字符串中最长的连续 '1' 的数量,然后判断这个数量是否正好等于9。

具体思路如下:

  1. 遍历字符串,用一个计数器记录当前连续 '1' 的数量
  2. 每当遇到一个 '1',计数器加1
  3. 每当遇到一个 '0',重置计数器为0
  4. 在整个过程中记录最大的连续 '1' 数量
  5. 最后判断最大连续数量是否等于9

这个算法的时间复杂度是 O(n),其中 n 是字符串的长度。我们只需要遍历一次字符串,并在遍历过程中更新最大连续计数即可。空间复杂度是 O(1),因为我们只使用了常数个变量来记录计数和最大值。

这种方法非常高效,可以轻松处理长度达到 10^5 的字符串。针对本题的特点,我们直接判断最大连续 '1' 的数量是否等于9,一旦发现连续数量超过9,就可以确定答案为 "unlucky"。

参考代码

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

# 读取测试数据的组数
T = int(input())
for _ in range(T):
    # 读取小径长度
    n = int(input())
    # 读取表示福娃分布的字符串
    s = input()
    
    # 初始化计数器和最大计数
    cnt = 0
    max_cnt = 0
    
    # 遍历字符串查找最长连续1的数量
    for c in s:
        if c == '1':
            # 如果当前字符是'1',计数器加1
            cnt += 1
            # 更新最大计数
            max_cnt = max(max_cnt, cnt)
        else:
            # 如果当前字符是'0',重置计数器
            cnt = 0
    
    # 判断最大连续1的数量是否正好等于9
    if max_cnt == 9:
        print("lucky")
    else:
        print("unlucky")
  • Cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    // 优化输入输出
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int T;
    cin >> T;
    
    while (T--) {
        int n;
        cin >> n;
        
        string s;
        cin >> s;
        
        // 初始化计数器和最大计数
        int cnt = 0, mx = 0;
        
        // 遍历字符串查找最长连续1
        for (char ch : s) {
            if (ch == '1') {
                // 福娃存在,计数器增加
                cnt++;
                // 更新最大值
                mx = max(mx, cnt);
            } else {
                // 福娃不存在,重置计数器
                cnt = 0;
            }
        }
        
        // 判断最大连续数量是否正好为9
        if (mx == 9) {
            cout << "lucky" << "\n";
        } else {
            cout << "unlucky" << "\n";
        }
    }
    
    return 0;
}
  • Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // 读取测试组数
        int t = sc.nextInt();
        
        while (t-- > 0) {
            // 读取小径长度
            int n = sc.nextInt();
            
            // 读取福娃分布字符串
            String s = sc.next();
            
            // 初始化计数器和最大值
            int curr = 0;
            int maxLen = 0;
            
            // 遍历字符串
            for (int i = 0; i < n; i++) {
                if (s.charAt(i) == '1') {
                    // 如果有福娃,计数器增加
                    curr++;
                    // 更新最大值
                    maxLen = Math.max(maxLen, curr);
                } else {
                    // 如果没有福娃,重置计数器
                    curr = 0;
                }
            }
            
            // 判断最大连续数量是否等于9
            if (maxLen == 9) {
                System.out.println("lucky");
            } else {
                System.out.println("unlucky");
            }
        }
        
        sc.close();
    }
}

02. 糖果店的优惠兑换计划

问题描述

小兰开了一家糖果店,推出了一种特殊的兑换活动。商店有 位顾客,每位顾客最多可以参与一次兑换,总共需要兑换完 个糖果。每张兑换券可以兑换 个糖果,但实际的兑换方式有点特别。

当顾客想兑换 个糖果时,需要的兑换券数量 按照以下公式计算:

也就是说,如果 ,则不需要消耗任何兑换券()。

小兰的规则是:

  • 每位顾客最多只能参与一次兑换活动
  • 所有 个糖果必须全部兑换完毕

小兰想知道,要兑换完所有糖果,至少需要多少张兑换券。请你帮忙计算。

输入格式

第一行包含一个正整数 ,表示测试数据组数。

接下来 行,每行包含三个正整数 ,分别表示顾客数量、需要兑换的糖果总数以及每张兑换券可兑换的糖果数量。

输出格式

输出 行,每行一个整数,表示最少需要的兑换券数量。

样例输入

2
3 300 100
2 100 160

样例输出

2
0

数据范围

样例 解释说明
3 300 100 有3位顾客,需要兑换300个糖果,每张券兑换100个。
当k=100时,可以免费兑换的最大糖果数为49个。
3位顾客共可免费兑换3×49=147个糖果。
剩余300-147=153个糖果需要使用兑换券。
使用2张兑换券可以再兑换2×100=200个糖果,足够覆盖剩余的153个。
因此最少需要2张兑换券。
2 100 160 有2位顾客,需要兑换100个糖果,每张券兑换160个。
当k=160时,可以免费兑换的最大糖果数为79个。
2位顾客共可免费兑换2×79=158个糖果。
这已经超过了需要兑换的100个糖果,因此不需要使用任何兑换券。
答案为0。

题解

这道题乍看有点复杂,但分析后会发现解题思路其实很清晰。

首先,我们需要理解兑换券的使用规则。通过分析给定的公式,我们可以得知,当兑换的糖果数量小于 k/2 时,不需要使用任何兑换券。这就意味着每位顾客都有一个"免费额度",可以不用兑换券就能兑换一定数量的糖果。

具体来说:

  • 当 k 为偶数时,免费兑换的最大糖果数量是 k/2 - 1
  • 当 k 为奇数时,免费兑换的最大糖果数量是 (k-1)/2

我们的策略是先利用所有顾客的免费额度,看能兑换多少糖果。如果这些免费额度总和已经超过了需要兑换的糖果总数 m,那么不需要使用任何兑换券。否则,我们需要计算还需要多少张兑换券来兑换剩余的糖果。

注意,每使用一张兑换券,就可以多兑换 k 个糖果。所以,剩余糖果数除以 k 并向上取整,就是我们需要的兑换券数量。

这个解法的时间复杂度是 O(T),其中 T 是测试数据的组数。每组数据我们只需要进行几个简单的计算即可。

空间复杂度是 O(1),因为我们只使用了常数个变量来存储中间结果。

对于给定的数据范围,我们需要使用长整型(long long)来处理可能的大数,特别是对于 n 和 m 这两个可能很大的输入。

参考代码

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

# 读取测试用例数量
T = int(input())

for _ in range(T):
    # 读取n, m, k
    n, m, k = map(int, input().split())
    
    # 计算每位顾客免费兑换的最大糖果数量
    if k % 2 == 0:
        # k为偶数
        free = k // 2 - 1
    else:
        # k为奇数
        free = (k - 1) // 2
    
    # 计算所有顾客总共可以免费兑换的糖果数量
    total_free = n * free
    
    if total_free >= m:
        # 免费额度足够,不需要兑换券
        print(0)
    else:
        # 计算还需要多少兑换券
        remain = m - total_free
        # 每张兑换券可以兑换k个糖果,向上取整
        coupons = (remain + k - 1) // k
        print(coupons)
  • Cpp
#include <iostream>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int t;
    cin >> t;
    
    while (t--) {
        long long n, m, k;
        cin >> n >> m >> k;
        
        // 计算每位顾客的免费额度
        long long free;
        if (k % 2 == 0) {
            // k为偶数
            free = k / 2 - 1;
        } else {
            // k为奇数
            free = (k - 1) / 2;
        }
        
        // 计算总免费额度
        long long tot = n * free;
        
        if (tot >= m) {
            // 免费额度足够
            cout << 0 << "\n";
        } else {
            // 需要使用兑换券
            long long need = m - tot;
            // 向上取整计算所需兑换券数量
            long long ans = (need + k - 1) / k;
            cout << ans << "\n";
        }
    }
    
    return 0;
}
  • Java
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // 读取测试用例数量
        int t = sc.nextInt();
        
        while (t-- > 0) {
            // 读取顾客数量n、糖果总数m和每张券兑换糖果数k
            long n = sc.nextLong();
            long m = sc.nextLong();
            long k = sc.nextLong();
            
            // 计算每位顾客的免费额度
            long fAmt;
            if (k % 2 == 0) {
                // k为偶数
                fAmt = k / 2 - 1;
            } else {
                // k为奇数
                fAmt = (k - 1) / 2;
            }
            
            // 计算总免费额度
            long total = n * fAmt;
            
            if (total >= m) {
                // 如果免费额度足够
                System.out.println(0);
            } else {
                // 计算需要的额外糖果数量
                long extra = m - total;
                // 向上取整计算所需兑换券
                long result = (extra + k - 1) / k;
                System.out.println(result);
            }
        }
        
        sc.close();
    }
}

03. 数字重排最大化问题

问题描述

小基是一位专业的数字设计师。她手中有两个数字序列 ,都由正整数组成。小基可以对序列 进行任意次操作,每次操作可以交换 中任意两个数字的位置。

小基的目标是让序列 组成的数字尽可能大,但必须严格小于序列 组成的数字。

请你帮助小基计算,在可以进行任意次交换操作后,符合条件的 所能组成的最大数字是多少。如果不存在符合条件的方案,请输出

输入格式

第一行包含一个正整数 ,表示测试数据的组数。

对于每组测试数据,分别有三行:

第一行包含两个正整数 ,分别表示序列 的长度。

第二行包含 个正整数,表示序列 的元素。

第三行包含 个正整数,表示序列 的元素。

输出格式

对于每组数据,输出一个整数,表示序列 经过任意次交换操作后,所能组成的最大且小于 的数字。

如果不存在这样的数字,则输出

样例输入

3
5 5
12345
45678
5 5
65479
54231
5 5
42315
12345

样例输出

45321
49765
-1

数据范围

  • 序列中的每个元素都是正整数(1-9)
样例 解释说明
5 5
12345
45678
序列s1=[1,2,3,4,5],序列s2=[4,5,6,7,8]
将s1重排为[4,5,3,2,1],组成的数字45321
这是小于s2组成的数字45678的最大可能值
5 5
65479
54231
序列s1=[6,5,4,7,9],序列s2=[5,4,2,3,1]
将s1重排为[4,9,7,6,5],组成的数字49765
这是小于s2组成的数字54231的最大可能值
5 5
42315
12345
序列s1=[4,2,3,1,5],序列s2=[1,2,3,4,5]
无论如何重排s1,都无法使其组成的数字小于s2
因此输出-1

题解

这道题需要我们

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

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

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

全部评论

相关推荐

06-03 19:56
门头沟学院 Java
建信融通有没有约一面的?到底是不是半结构化面试?附一篇拼多多面经1.使用Redis解决集群模式下的session共享问题,是把session存在Redis里了吗?我说存的是用户信息,不是session2.那你请求传过来的是什么?key是UUID+用户id,3.那你怎么知道传过来什么呢?我说登录后返回一个token,放在请求头的authorization里4.前端是你写的吗?不是5.那你怎么通过redis&nbsp;template获取数据?就是通过redis直接去呀,根据uuid+用户id6.为什么要用随机值?就是加一个校验机制二、分布式锁1.一人一单集群下分布式锁是怎么用的?Key为用户id&nbsp;+&nbsp;业务名,自定义分布式锁,或者用的是Redisson2.怎么实现的自定义锁,自定义和Redisson有什么区别Setnx,看门狗机制、重入比较难实现,用他封装好的3.看门狗机制解决什么问题?超时释放4.反问能解决超时释放吗?能,说到了判断锁是否被持有5.如何判断锁是否被持有不知道6.都要用&nbsp;用户id吗?不是,根据业务需求来,如果是库存超卖,那应该是商品id+业务三、Rabbitmq1.我看你第二个项目说用到了rabbitmq,你对几个消息队列的中间件有什么了解,他们有什么区别?说了rabbitmq&nbsp;和&nbsp;rocketmq,说了rocket可能更加可靠2.消息队列可靠是什么意思&nbsp;?保证消息被消费,消息不丢失3.什么情景&nbsp;rocketmq能做到,rabbitmq不能做不知道四、Zset1.为什么要用zset,不用其他的数据结构我说压缩列表和跳表2.什么情况下是跳表什么情况下是压缩列表设置&nbsp;&nbsp;长度&nbsp;&nbsp;1283,为什么要从压缩列表换成跳表增删的性能4.增删性能好的数据结构很多,为什么用跳表我说相比于链表,跳表可以实现范围查询5.实现范围查询,为什么不用B+树?B+树空间太大五、MySQL1.mysql熟悉吧?还可以2.Mysql都用到了什么锁表级锁、行级锁3.什么情况用表级锁、什么情况用行级锁表结构变化才用表级锁,一般情况只用行级锁4.行级锁又会锁那几行,举例一下不知道5.事务了解吧,都有哪几种事务?开始吟唱6.它们的实现有什么不同?锁和MVCC机制,开始吟唱7.不可重复读是什么问题?开始吟唱8.在开发中,经常用读已提交是为什么?你知道吗?不太依赖事务追求性能六、JVM1.G1&nbsp;回收器知道吗?2.你了解哪些回收机制?七、计算机网络1.滑动窗口是如何进行拥塞控制的?拥塞窗口:1.慢启动,拥塞窗口从1个报文段开始,每收到一个ACK,指数增长(*2)直到达到慢启动阈值或者发生丢包(超时/重复ack)2.拥塞避免,当拥塞窗口大小大于等于&nbsp;ssthresh(慢启动阈值),转为线性增长,避免窗口过大导致网络拥塞3.拥塞处理,丢包A.超时,严重拥塞,ssthresh置为&nbsp;cwnd/2,&nbsp;cwnd(拥塞窗口)置为1,重新慢启动B.重复ack,轻微拥塞,触发快速重传/快速恢复,ssthresh置为cwnd/2,cwnd也减半后线性增长接收窗口:由接收方通过TCP头部通告,表示其剩余缓冲区大小发送窗口&nbsp;=&nbsp;min(接收窗口,拥塞窗口),发送方在任意时刻可以连续发送但尚未收到确认的数据量,由接收窗口和接收窗口共同决定,确保数据发送既不会导致网络拥塞,也不会超过接收方的处理能力。2.HTTPS对比HTTP为什么是安全的?HTTPS&nbsp;=&nbsp;HTTP+加密+身份认证+完整性保护·加密传输(防窃听),HTTP以明文传输,攻击者可以直接截获通信内容;HHTPS使用SSL/TLS协议对数据进行加密(AES、RSA算法),即使被截获也无法解密·身份验证,HTTP无法验证服务器身份,攻击者可以伪造虚假网站;HTTPS通过数字证书(CA)验证网站的真实性,浏览器会显示锁图标,点击可查看证书信息,若证书无效,会提示警告·数据完整行,HTTP数据在传输中可能被修改(如插入广告或者恶意代码),而HTTPS使用消息认证码(MAC)或者哈希校验,确保数据未被修改。&nbsp;&nbsp;原理:TLS协议会为数据生成唯一指纹,接收方校验指纹是否匹配。手撕算法1.求链表的公共节点2.合并两个有序链表
查看4道真题和解析
点赞 评论 收藏
分享
三题看不懂四题不明白二题无法AC&nbsp;&nbsp;T=int(input())&nbsp;for&nbsp;_&nbsp;in&nbsp;range(T):&nbsp;n=int(input())&nbsp;s=input().split()&nbsp;k,mx=1,1&nbsp;for&nbsp;i&nbsp;in&nbsp;range(len(s)-1):&nbsp;if&nbsp;len(s[i])&lt;len(s[i+1]):&nbsp;k+=1&nbsp;elif&nbsp;len(s[i])==len(s[i+1]):&nbsp;if&nbsp;s[i]&lt;=s[i+1]:&nbsp;k+=1&nbsp;else:&nbsp;mx=max(mx,k)&nbsp;k=1&nbsp;mx=max(mx,k)&nbsp;else:&nbsp;mx=max(mx,k)&nbsp;k=1&nbsp;mx=max(mx,k)&nbsp;print(mx)&nbsp;=====&nbsp;##过了...
恭喜臭臭猴子:第二题用栈就行。合法的括号直接出栈了,剩下的是不合法的,肯定都得一个一个走。出入栈的过程中得记下进栈的括号的下标。最后栈里剩下的括号如果相邻两个的下标不连续,说明它们中间有一个合法的括号序列被出栈,结果加一
投递拼多多集团-PDD等公司10个岗位
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

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