【字节跳动高频面试题】不超过 N 的最大数拼接
【字节跳动高频面试题】不超过 N 的最大数拼接
题目描述
给定一个按 非递减顺序 排列的数字字符数组 digits(如 ["1","3","5","7"]),你可以任意次数使用这些字符,拼接成一个正整数。
请返回:所有能拼出且 ≤ 给定整数 n 的正整数中,值最大的那个。
示例
输入:digits = ["1","3","5","7"], n = 100
输出:77
解法一:暴力回溯(Backtrack 贪心)
思路概览
我们希望构造一个不大于 n 的数,且尽可能大。每一位从高位到低位逐位尝试:
若该位能找到一个
≤ s[i]的最大字符d:- 如果
d == s[i],继续匹配下一位; - 如果
d < s[i],则当前为转折点,后面全部填digits中最大值,直接构成答案;
- 如果
如果该位没有合法字符(即所有字符都 >
s[i]),则需要回退(Backtrack):- 回退到前一位,寻找一个更小字符,之后所有位都填最大字符。
若所有位都成功对齐 n 的每一位字符,则答案为 n 本身。否则返回构造出的最大值。
时间复杂度分析
最坏情况每一位都需要回退多次;
时间复杂度约为
O(L × |digits|),其中:L = log10(n) + 1为位数;|digits| ≤ 9。
即便 n 非常大(如 10^18),依然能在毫秒级别内完成。
C++ 实现
int bytedance1(vector<string>& digits, int n) {
bool flag = false; // 是否已经满足 <,之后可以直接填最大digit
string s = to_string(n);
n = s.size();
unordered_map<char, int> mp;
for(int i = 0; i < digits.size(); i++) mp[digits[i][0]] = i + 1;
vector<char> res(n, digits[0][0]);
for(int i = 0; i < n && !flag; i++) {
for(auto& d : digits) {
if(d[0] <= s[i]) res[i] = d[0];
}
if(res[i] < s[i]) {
flag = true;
for(int j = i + 1; j < n; j++) res[j] = digits.back()[0];
} else if(res[i] > s[i]) { // 无法继续匹配
int j = i;
while(j >= 0 && res[j] == digits[0][0]) j--;
if(j == -1) {
res.resize(n - 1, digits.back()[0]);
} else {
for(auto& d : digits) {
if(d[0] < s[j]) res[j] = d[0];
}
j++;
for(; j < n; j++) res[j] = digits.back()[0];
}
flag = true;
}
}
for(auto& ch : res) cout << ch;
cout << endl;
return 0;
}
解法二:数位 DP(Digit DP)
解题框架
使用数位 DP 框架模板,通过参数限制合法性。
L:下界,补齐成和R同样的位数(例如"001");R:上界,即n;digits:枚举所有合法的数字;状态参数:
i:当前位;isZero:是否还处于前导零;isLow:当前是否仍受下界限制;isHigh:当前是否仍受上界限制。
关键转移逻辑
int dfs(int i, int isZero, int isLow, int isHigh);
- 当
isZero && l == 0时,可以跳过当前位; - 当
!isZero && !isLow && !isHigh时,结果可以记忆化缓存; - 尝试填入所有合法的
digits中的数字,满足边界限制即可。
C++ 实现
string L, R;
vector<int> digits;
int n, f[10];
string tmp = "", res = "";
int dfs(int i, int isZero, int isLow, int isHigh) {
if(i == n) {
if(res == "") res = tmp; // 保存最大值
return !isZero;
}
if(!isZero && !isLow && !isHigh && ~f[i]) return f[i];
int l = isLow ? L[i] - '0' : 0;
int r = isHigh ? R[i] - '0' : 9;
int ans = 0;
for(int& d : digits) {
if(d >= l && d <= r) {
tmp.push_back(d + '0');
ans += dfs(i + 1, 0, isLow && d == l, isHigh && d == r);
tmp.pop_back();
}
}
if(isZero && l == 0) ans += dfs(i + 1, 1, 1, isHigh && r == 0);
if(!isZero && !isLow && !isHigh) f[i] = ans;
return ans;
}
int bytedance2(vector<string>& digitsStr, int n) {
R = to_string(n);
L = string(R.size() - 1, '0') + "1";
::n = R.size();
digits.clear();
for(auto& x : digitsStr) digits.emplace_back(x[0] - '0');
ranges::reverse(digits); // 从大到小尝试
memset(f, -1, sizeof f);
dfs(0, 1, 1, 1);
cout << res << endl;
return 0;
}
LeetCode 原题推荐
- 类型:数位 DP
- 难度:中等
- 高频企业题:字节跳动、美团、阿里
总结
| 方法 | 思路 | 优点 | 缺点 |
|---|---|---|---|
| 回溯贪心法 | 模拟构造 | 逻辑直观,易于调试 | 实现较繁琐,回退处理需细致 |
| 数位 DP | 状态转移+缓存 | 可扩展,适合复杂限制条件 | 学习门槛略高,状态较多 |
【字节跳动高频面试题】不超过 N 的最大数拼接的更多相关文章
- 字节跳动-前端面试题 Multi Promise Order
字节跳动-前端面试题 Multi Promise Order Promise Order Async/Await async function async1 () { console.log('asy ...
- 双非本科字节跳动Android面试题分享(已拿offer)
基本情况 本人系非985非211普通本科生一枚,有实习有项目经历但成绩普通,在面试前刷了很多面经.面试题,这里也把自己的分享下,做个回报好了,顺便攒攒人品,一到这种时候人就迷信起来了. 面试是以视频面 ...
- 字节跳动社会招聘&内推-帮助你更快加入字节跳动
字节跳动社会招聘&内推「[内推码]:4J8CA3W」 内推时间:一直有效 招聘对象:根据招聘要求而定 社招投递链接: https://job.toutiao.com/s/de5teaA 应届生 ...
- 字节跳动Android实习面试难吗,应该如何应对?
字节跳动的面试难不难其实很难去非常准确的定义,但是能肯定的一点是,字节跳动的面试题都很有水平,真正考察了该岗位在以后工作中需要的能力. 大学学的Java后面又自学Android方向,跟着老师在实验室做 ...
- 2019 字节跳动java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.字节跳动等公司offer,岗位是Java后端开发,因为发展原因最终选择去了字节跳动,入职一年时间了,也成为了面 ...
- 最新 字节跳动java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.字节跳动等10家互联网公司的校招Offer,因为某些自身原因最终选择了字节跳动.6.7月主要是做系统复习.项目复盘.Leet ...
- 多次面试被拒,‘宅家苦修’30天,终获美团offer(含字节跳动/阿里/腾讯等大厂面试题整理)
背景:双非渣本. 今年由于疫情,上半年一直在家里.2月份本来无忧无虑,呆在家里不给国家添乱的时候,发现身边的同学找到了大厂的offer.心里开始有点慌张.本来想在3月份如果能回到学校,就开始考研之路, ...
- 从阿里、腾讯的面试真题中总结了这11个Redis高频面试题
前言 现在大家的工作生活基本已经是回归正轨了,最近也是迎来了跳槽面试季,有些人已经拿到了一两个offer了. 这段时间收集了阿里.腾讯.百度.京东.美团.字节跳动等公司的Java面试题,总结了Redi ...
- 字节跳动实习面经分享(已拿offer附攻略)
大家好,我是bigsai,今天给大家分享自己字节跳动面试经验分享. enum我面得岗位是后台实习开发,具体部门是懂车帝,总体感觉就是字节的流程真的好快,只要安排面试,那流程接着很快. 大概是上上周投递 ...
- 一份热乎的字节跳动客户端面经,已拿Offer
字节面试过程: 4月4号进行内推,7天的简历评估,11号接到电话面试,尽管猝不及防回答仓促,但好在前期准备充分,通过.14号现场面试,次日收到通知,通过,二面.三面都很顺利.20号进行HR面,26号收 ...
随机推荐
- CM311-1A魔百和刷armbian或openwrt系统包
系统包下载链接:Openwrt:阿里云盘链接:https://www.aliyundrive.com/s/tEemRbs1TYB已失效下载后请解压!!!!!!!!! Armbian:链接:https: ...
- 基于源码分析 HikariCP 常见参数的具体含义
HikariCP 是目前风头最劲的 JDBC 连接池,号称性能最佳,SpringBoot 2.0 也将 HikariCP 作为默认的数据库连接池. 要想用好 HikariCP,理解常见参数的具体含义至 ...
- Asp.net mvc基础(六)TempData
在客户端重定向或验证码等情况下,由于要跨请求的存取数据,是不能放到ViewBag.Model中,需要"暂时存到Session中,用完了删除"的需求:使用TempData可以做到. ...
- issue: java.lang.NoClassDefFoundError: javax/el/ELManager
问题描述: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error c ...
- 搞定 XLSX 预览?别瞎找了,这几个库(尤其最后一个)真香!
- Hey, 我是 沉浸式趣谈 - 本文首发于[沉浸式趣谈],我的个人博客 **https://yaolifeng.com** 也同步更新. - 转载请在文章开头注明出处和版权信息. - ...
- Python3批量爬取美女照片并保存到本地(二)
Python3批量爬取美女照片并保存到本地(二) 上一波写错了,很尴尬,就能爬显示的一部分照片,网站有限制,从上波的爬取可以看出来,返回的json中只有一部分图片,其余的需要登录才能下载,我们这次通过 ...
- C语言函数指针解析
C语言函数指针解析 一.函数指针的本质 函数指针是存储函数内存地址的变量,它允许程序在运行时动态调用不同的函数.与数据指针不同,函数指针指向的是可执行代码段. /* 典型声明方式 */ int (*f ...
- codeup之冒泡排序
Description 从键盘上输入10个整数,用冒泡法对这10个数进行排序(由小到大). Input 以空格分隔的10个整数 Output 依次输出排好序的10个整数,每个数占一行. Sample ...
- stopPropagation()方法阻止父级事件
方式一 <div id="div1"> <div id="div2"></div> </div> $(" ...
- 20244104 实验二《Python程序设计》实验报告
课程:<Python程序设计> 班级: 2441 姓名: 陈思淼 学号:20244104 实验教师:王志强 实验日期:2025年4月5日 必修/选修: 公选课 1.实验内容 设计并完成一个 ...