当前位置: 首页 > news >正文

丑数II C++三指针解法(力扣264)

问题解构:LeetCode 264题“丑数II”要求找出第n个丑数。丑数定义为只包含质因数2、3、5的正整数(1通常被视为第一个丑数)。核心挑战在于高效生成有序的丑数序列,避免对每个数进行质因数分解判断(效率极低)。

方案推演:高效解法主要基于动态规划与三指针技术。思路是每个丑数都可以由之前的某个丑数乘以2、3或5得到。使用三个指针p2p3p5分别记录下一个可能乘以2、3、5的丑数位置,每次取生成值的最小值作为新丑数,并更新对应指针。

以下是完整的C++代码实现,包含详细注释。

#include <vector> #include <algorithm> using namespace std; class Solution { public: int nthUglyNumber(int n) { // 使用动态规划数组dp存储已生成的丑数 vector<int> dp(n); dp[0] = 1; // 第一个丑数是1 // 初始化三个指针,分别指向下一个将要乘以2、3、5的丑数位置 int p2 = 0, p3 = 0, p5 = 0; for (int i = 1; i < n; ++i) { // 生成下一个丑数的三个候选值 int num2 = dp[p2] * 2; int num3 = dp[p3] * 3; int num5 = dp[p5] * 5; // 下一个丑数是三个候选值中的最小值 int nextUgly = min({num2, num3, num5}); dp[i] = nextUgly; // 关键步骤:更新指针。如果候选值被选中,其对应的指针后移一位。 // 注意:使用if而非else if,因为可能存在多个候选值相等的情况(例如6=2*3),需要同时移动指针以避免重复。 if (nextUgly == num2) { p2++; } if (nextUgly == num3) { p3++; } if (nextUgly == num5) { p5++; } } // 返回第n个丑数 return dp[n - 1]; } };

算法核心逻辑与示例

该算法通过维护三个指针p2p3p5和一个丑数序列dp,确保每次都能以O(1)的时间找到下一个丑数。其工作原理如下表所示:

步骤 (i)dp[i] (丑数)p2 (乘2基准)p3 (乘3基准)p5 (乘5基准)候选值 (num2, num3, num5)选中值指针更新
初始dp[0]=10 (dp[0]=1)0 (dp[0]=1)0 (dp[0]=1)(2, 3, 5)2p2++
i=121 (dp[1]=2)0 (dp[0]=1)0 (dp[0]=1)(4, 3, 5)3p3++
i=231 (dp[1]=2)1 (dp[1]=2)0 (dp[0]=1)(4, 6, 5)4p2++
i=342 (dp[2]=3)1 (dp[1]=2)0 (dp[0]=1)(6, 6, 5)5p5++
i=452 (dp[2]=3)1 (dp[1]=2)1 (dp[1]=2)(6, 6, 10)6p2++, p3++

以上模拟展示了生成前6个丑数(1, 2, 3, 4, 5, 6)的过程。特别需要注意的是步骤i=4,候选值num2num3都等于6,此时p2p3需要同时递增,以防止后续序列中出现重复的丑数(如另一个6)。

复杂度分析

  • 时间复杂度:O(n)。只需进行单层循环生成n个丑数,每次循环内的操作是常数时间。
  • 空间复杂度:O(n)。需要长度为n的数组dp来存储丑数序列。

性能优化提示
在实际提交中,可以利用C++类的静态变量进行缓存优化。即,将丑数数组dp声明为静态变量,这样在多次调用nthUglyNumber函数时,可以复用之前计算好的丑数序列,避免重复计算,尤其适合在线判题系统的多组测试用例场景。

// 优化版本:使用静态变量缓存丑数序列 class SolutionOptimized { public: int nthUglyNumber(int n) { static vector<int> dp; static int p2 = 0, p3 = 0, p5 = 0; if (dp.empty()) { dp.push_back(1); } while (dp.size() < n) { int nextUgly = min({dp[p2] * 2, dp[p3] * 3, dp[p5] * 5}); dp.push_back(nextUgly); if (nextUgly == dp[p2] * 2) p2++; if (nextUgly == dp[p3] * 3) p3++; if (nextUgly == dp[p5] * 5) p5++; } return dp[n - 1]; } };

此优化版本在首次调用或需要扩展序列时进行计算,之后调用直接返回缓存结果,显著提升效率。


参考来源

  • LeetCode第264题_丑数II
  • 一文搞定丑数 II!LeetCode 264「丑数 II」两大解法多语言题解
  • LeetCode第263题_丑数
  • c++中static关键字 —— leetcode264
  • LeetCode 264. Ugly Number II--C++,Python解法
  • Leetcode 264. 丑数 II 解题思路及C++实现
http://www.jsqmd.com/news/799170/

相关文章:

  • 鸿蒙洪荒华夏神话体系——全域兼容典籍收录总名录
  • 99%的老师用AI,都只用了最没用的那一层
  • KDE面板背景个性化设置技巧
  • 算法精析——红外小目标检测中Local Contrast Measure(局部对比度测量)的工程实现与优化
  • Hugging Face模型压缩超快
  • DeepSeek API Gateway灰度发布全链路实践:支持模型版本A/B测试、流量染色、动态路由的5步标准化流程
  • OpenBMC:从嵌入式控制器到开源数据中心管理平台的演进之路
  • Python新手必看:处理ValueError: invalid literal for int() with base 10的3种实用方法
  • Hyperf 能够识别 PSR-7 标准接口,自动注入当前请求的对象。
  • AI技能文件管理工具agent-skills-lint:多助手环境下的统一质检方案
  • GPT Image 2 国内怎么上手?普通人做封面、海报、商品图之前,先搞懂这 6 件事
  • 2026年5月新消息:桐城百货青睐的塑料袋实力厂家深度解析 - 2026年企业推荐榜
  • DIY一个高性价比温湿度计:AHT10对比DHT11/SHT20,硬件选型与成本分析
  • 别再盲目订阅!2024最严苛AIGC采购评估表(含SLA响应时间、商用版权链路、NSFW过滤强度、企业SSO支持度)——Midjourney与DALL-E 3逐项打分揭晓
  • TongWeb日志排查实战:从server.log里揪出Nacos连接失败的‘元凶’
  • 第 1 周 Day 3:Python Agent 调用大模型 API:封装 LLMClient
  • 2026届最火的五大AI写作神器横评
  • Perplexity ScienceDirect跨库语义检索黑箱破解(基于BERT-SciBERT双编码器对比实验,含17组F1-score基准数据)
  • 从‘粘在中间’到‘钉在底部’:一个新手前端用CSS解决footer定位的踩坑全记录
  • 2026年5月新发布:太原全屋定制实力机构盘点,索菲亚黎氏阁总店引领品质生活 - 2026年企业推荐榜
  • VCF 9.1 新特性:安装器与 Fleet Depot 支持 HTTP 无认证离线软件源
  • 2026届学术党必备的十大AI写作神器推荐
  • Hyperf 默认的控制器都是走协程吗?
  • 打破刻板逻辑:过来人实测3款降AI工具,手把手教你论文稳过安全线
  • 超越简单计数:用YOLO+DeepSORT分析店铺客流轨迹,优化运营的实战思路
  • 别再被网速劝退!手把手教你用Gitee镜像源在Ubuntu 18.04上快速搭建Autoware.ai
  • 2026年最新山东流利货架工厂实力盘点与推荐 - 2026年企业推荐榜
  • 4月视频模型竞争激烈:巨头三强争榜单与用户,二梯队分化,Sora退场凸显ROI困境
  • 基于Rsoft仿真的光栅薄膜光学性能优化与设计实践
  • 2026年当下,乡宁县油烟机选购指南:为何“尧新电器批发”是您的理想之选? - 2026年企业推荐榜