【字节跳动高频面试题】不超过 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号收 ...
随机推荐
- JSON Objects Framework(1)
学习datasnap,json必须掌握.用自身的JSON,就必须熟悉JSON Objects Framework.其中tostring和value区别就是一个坑. The JSON objects f ...
- FastAPI 核心安全功能与模板渲染的完整示:登录、CSRF、JWT、会话、认证和缓存功能
以下是一个整合 FastAPI 核心安全功能与模板渲染的完整示例,基于多个技术文档的最佳实践,包含登录.CSRF.JWT.会话.认证和缓存功能: from datetime import dateti ...
- 为什么不推荐在 MySQL 中直接存储图片、音频、视频等大容量内容?
在MySQL中直接存储图片.音频.视频等大容量内容(通常称为BLOB数据)通常不被推荐,主要原因包括以下几点: 1. 性能问题 存储效率:存储大容量文件(如图片.音频.视频等)会大幅增加数据库的存储负 ...
- 在 .NET 中的 ConvertAll 和 Select 方法哪个性能好
.NET 的 List 中提供了 ConvertAll 和 Select 两个方法,在开发中实际上应该使用哪一个? 接下来通过基准测试脚本来对比性能. 先编写基准测试脚本: [MemoryDiagno ...
- 题解:CF1955E Long Inversions
简单题. 考虑贪心地进行修改,每次选择字符串中最左侧第一个 000,并以该位置为左端点进行一次修改,可以发现若 lenlenlen 合法则这样一定构造出全 111 串. 然而直接暴力实现是 O(n2) ...
- 16.1k star! 只需要DDL就能一键生成数据库关系图!开源神器ChartDB让你的数据结构"看得见"
嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 ChartDB是一款开源的数据库可视化神器,通过一句智能查询就能自动生成专业的数据库关系图. ...
- 原生JS表格数据常用总结
主要是在数据报表这块, 做了好几年发现, 其实用户最终想要看的并不是酷炫的BI大屏, 而是最基础也是最复杂的 中国式报表. 更多就是倾向于从表格中去获取数据信息, 最简单的就是最好的, 于是还是来总结 ...
- TVM:Schedule的理解
schedule与计算逻辑分离是自动代码生成技术的核心概念,由MIT CASIL组的Jonathan Ragan-Kelley在2012年发表在SIGGRAPH上的文章率先提出,然后在2013年发表在 ...
- 用C#将多个jpg合成一个pdf
nuget安装iTextSharp: static void MergePDF(string picPath,string pdfPath) { string[] picFileNames=Direc ...
- 2.2.net core 工作流WorkFlow流程(流程设计)
流程设计 WikeFlow官网:http://www.wikesoft.com WikeFlow学习版演示地址:http://workflow.wikesoft.com WikeFlow学习版源代码下 ...