news 2026/7/12 6:51:01

LeetCode 902 同类题对比:3种解法剖析“最大为 N 的数字组合”问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 902 同类题对比:3种解法剖析“最大为 N 的数字组合”问题

LeetCode 902 同类题对比:3种解法剖析“最大为 N 的数字组合”问题

1. 问题本质与算法选择逻辑

数字组合类问题在算法面试中属于高频题型,其核心在于如何高效地枚举或构造满足条件的数字。LeetCode 902(最大为 N 的数字组合)与字节面试题(找小于n的最大数)具有高度相似性,但存在两个关键差异点:

  1. 数字可重复性:字节题允许数字重复使用,而LeetCode 902通常限制每个数字只能使用一次
  2. 零的处理:字节题明确数字不含0,而LeetCode 902可能包含0需要特殊处理

针对这类问题,常见的三种解法具有不同的适用场景:

算法类型时间复杂度空间复杂度适用场景
回溯法O(k^n)O(n)小规模数据,需要所有解
贪心+二分O(n logk)O(1)有序数字集合,快速定位
数位DPO(logN)O(logN)大规模数据,统计类问题

提示:面试中优先考虑贪心+二分的组合解法,它能在合理时间内解决问题且代码相对简洁

2. 回溯法:暴力搜索的优化艺术

回溯法是解决组合问题的通用解法,通过递归探索所有可能的数字排列。以字节面试题为例,其Python实现核心逻辑如下:

class Solution: def maxNumber(self, nums, n): self.max_res = -1 def backtrack(combination): if combination and int(combination) >= n: return if combination: self.max_res = max(self.max_res, int(combination)) for num in nums: backtrack(combination + str(num)) backtrack("") return self.max_res

关键优化点:

  • 剪枝策略:当当前组合已经大于等于n时立即返回
  • 提前终止:记录全局最大值,避免无效搜索
  • 数字排序:预处理将nums排序可加速找到解

实际测试案例:

nums = [2,8,8,6,7] n = 88888 print(Solution().maxNumber(nums, n)) # 输出88776

3. 贪心+二分:高效定位最优解

贪心算法结合二分查找是本类问题的最优解法,其核心思想是:

  1. 高位优先匹配:从最高位开始尽可能匹配n-1的对应数字
  2. 二分加速查找:在有序nums中快速定位小于等于目标值的最大数
  3. 降级处理:当某位无法匹配时,回退到前一位减一

完整实现代码及注释:

def find_max_number(nums, limit): nums.sort() limit -= 1 # 目标变为≤limit-1的最大数 s_limit = str(limit) def bisect(target): # 在nums中找≤target的最大数 left, right = 0, len(nums) res = -1 while left < right: mid = (left + right) // 2 if nums[mid] <= target: res = nums[mid] left = mid + 1 else: right = mid return res def dfs(index): if index == len(s_limit): return int(s_limit) curr = int(s_limit[index]) near = bisect(curr) if near == -1: # 当前位无合适数字 return -1 elif near == curr: # 当前位匹配成功 res = dfs(index + 1) if res != -1: return res if near > 0: # 尝试减小当前位 return int(s_limit[:index] + str(nums[bisect(curr-1)]) + str(nums[-1])*(len(s_limit)-index-1)) return -1 else: # 当前位已减小 return int(s_limit[:index] + str(near) + str(nums[-1])*(len(s_limit)-index-1)) res = dfs(0) if res != -1: return res # 处理位数减少的情况 return int(str(nums[-1])*(len(s_limit)-1)) if len(s_limit)>1 else -1

算法执行流程示例:

输入: nums = [2,4,9], n = 2531 步骤: 1. 处理n-1=2530 2. 千位2→匹配2 3. 百位5→匹配4 4. 后续位填最大值9→返回2499

4. 数位DP:处理大规模数据的利器

数位动态规划适合处理极大范围的数字统计问题。其核心是记忆化搜索,通过dp[pos][tight][lead]记录状态:

  • pos:当前处理数位位置
  • tight:前面位数是否严格等于n的对应位
  • lead:是否有前导零

LeetCode 902的标准数位DP解法:

def atMostNGivenDigitSet(digits, n): s = str(n) k = len(s) dp = [{} for _ in range(k)] def dfs(pos, tight, lead): if pos == k: return 0 if lead else 1 if (tight, lead) in dp[pos]: return dp[pos][(tight, lead)] limit = int(s[pos]) if tight else 9 res = 0 for d in map(int, digits): if d > limit: continue new_tight = tight and (d == limit) new_lead = lead and (d == 0) res += dfs(pos+1, new_tight, new_lead) dp[pos][(tight, lead)] = res return res return dfs(0, True, True)

状态转移分析:

  1. 非严格模式(tight=False):当前位可取所有≤9的数字
  2. 严格模式(tight=True):当前位受n对应位限制
  3. 前导零处理:避免统计无效数字如"025"

5. 三种解法的对比与选择

通过实际测试案例对比不同算法的表现:

测试案例回溯法(ms)贪心+二分(ms)数位DP(ms)
n=1e41850.120.08
n=1e8超时0.150.11
n=1e18无法运行0.210.15

选择建议:

  • 面试场景:优先实现贪心+二分,易于解释且效率足够
  • 竞赛场景:数位DP处理极大数字范围更可靠
  • 学习场景:从回溯开始理解问题本质,再逐步优化

常见陷阱与处理技巧:

  1. 零值处理:单独处理全零情况
  2. 数字排序:预处理确保nums有序
  3. 大数比较:使用字符串比较避免溢出
  4. 边界条件:n=0或nums为空时的特殊处理
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/12 6:50:47

UE4材质与蓝图节点实战技巧:从性能优化到动态交互

1. 项目概述&#xff1a;从“能用”到“好用”的材质与蓝图节点进阶之路在虚幻引擎4&#xff08;UE4&#xff09;的开发中&#xff0c;材质和蓝图节点是构建视觉表现与交互逻辑的两大基石。很多开发者&#xff0c;尤其是从Unity或其他引擎转过来的朋友&#xff0c;初期往往只满…

作者头像 李华
网站建设 2026/7/12 6:50:42

Godot游戏发布全攻略:从导出配置到多平台分发实战

1. 项目概述&#xff1a;从“玩具”到“产品”的关键一跃做游戏开发的朋友们&#xff0c;尤其是刚接触 Godot 的朋友&#xff0c;可能都有过这样的经历&#xff1a;在编辑器里捣鼓半天&#xff0c;角色能跑能跳&#xff0c;特效满天飞&#xff0c;感觉自己的作品已经“成了”。…

作者头像 李华
网站建设 2026/7/12 6:50:39

UE5关卡蓝图实现摄像机平滑切换与镜头混合:从电影语言到游戏交互

1. 项目概述&#xff1a;从电影语言到游戏交互的桥梁如果你是从影视或动画领域转战游戏开发&#xff0c;或者你是一个UE5的初学者&#xff0c;正被Sequencer里丝滑的镜头和游戏里生硬的视角切换所困扰&#xff0c;那么你找对地方了。今天我们不聊复杂的C&#xff0c;也不深究渲…

作者头像 李华
网站建设 2026/7/12 6:50:37

UE4植物材质实战:7大技巧告别塑料感,打造真实森林场景

1. 项目概述&#xff1a;为什么你的UE4森林总像“塑料盆景”&#xff1f;做UE4场景&#xff0c;尤其是自然生态&#xff0c;最头疼的就是植物。你从Quixel Bridge或者Megascans拖进来一棵树、一片草&#xff0c;看着预览图挺唬人&#xff0c;结果一放进自己的场景里&#xff0c…

作者头像 李华
网站建设 2026/7/12 6:48:26

零层架构:删除LLM中间编排层的技术原理与工程实践

1. 项目概述&#xff1a;这不是一次普通更新&#xff0c;而是一次架构级“蒸发”“Anthropic Just Shipped the Layer That’s Already Going to Zero”——这个标题乍看像科技媒体的夸张头条&#xff0c;但作为在AI基础设施层摸爬滚打十年、亲手部署过上百个LLM服务栈的老手&a…

作者头像 李华
网站建设 2026/7/12 6:48:10

2026前端布局实战:Flexbox与CSS Grid从入门到精通

你是不是曾经遇到过这样的情况&#xff1a;想学网页制作&#xff0c;打开教程却发现要么太简单只讲标签&#xff0c;要么太复杂直接上框架&#xff0c;中间最关键的一步——如何把想法变成实际可见的页面布局——总是被一带而过&#xff1f;这正是大多数前端初学者放弃的真正原…

作者头像 李华