您的位置:首页 > Web前端

剑指 Offer 49. 丑数

2021-09-14 17:55 513 查看

剑指 Offer 49. 丑数

我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

示例:

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。

说明:

  • 1 是丑数。
  • n 不超过1690。

做题思路:

丑数的递推性质: 丑数只包含因子 2, 3, 5 ,因此有 “丑数 == 某较小丑数 × 某因子” (例如:10 = 5×2)。

个人理解: 将丑数数组分为以 2、3 和 5为因子的子数组, 分别以子数组为基数往后递推, 取最小的为dp[i], 此时子数组index++;

举例说明:

i = 2时,n2 = 4, n3 = 3, n5 = 5 ,dp[2] = 2

i = 3时,n2 = 4, n3 = 6, n5 = 5 ,dp[3] = 3

i = 4时,n2 = 4, n3 = 6, n5 = 5 ,dp[4] = 4

i = 5时,n2 = 6, n3 = 6, n5 = 5, dp[5] = 5

然后返回dp[5]

class Solution {
public int nthUglyNumber(int n) {
int[] dp = new int
;  // 使用dp数组来存储丑数序列
dp[0] = 1;  // dp[0]已知为1
int a = 0, b = 0, c = 0;    // 下个应该通过乘2来获得新丑数的数据是第a个, 同理b, c

for(int i = 1; i < n; i++){
// 第a丑数个数需要通过乘2来得到下个丑数,第b丑数个数需要通过乘2来得到下个丑数,同理第c个数
int n2 = dp[a] * 2, n3 = dp[b] * 3, n5 = dp[c] * 5;
dp[i] = Math.min(Math.min(n2, n3), n5);
if(dp[i] == n2){
a++; // 第a个数已经通过乘2得到了一个新的丑数,那下个需要通过乘2得到一个新的丑数的数应该是第(a+1)个数
}
if(dp[i] == n3){
b++; // 第 b个数已经通过乘3得到了一个新的丑数,那下个需要通过乘3得到一个新的丑数的数应该是第(b+1)个数
}
if(dp[i] == n5){
c++; // 第 c个数已经通过乘5得到了一个新的丑数,那下个需要通过乘5得到一个新的丑数的数应该是第(c+1)个数
}
}
return dp[n-1];
}
}

如果还是不怎么懂,可以看一下这个力友一个解释吧,我觉得比较好理解一点。

可以这样理解: 有三匹马在赛跑,a马跑的最慢,b马中等,c马跑的最快 遵循一个原则,跑的慢可以先跑,但是跑的远了,就得后跑 一开始a马速度慢,所以a先跑2米, 然后b马也慢,b马跑3米, 然后a马跑的太慢了,让他先跑也只跑了两米,所以再让他先跑,所以此时 a马跑了4米,b马跑了3米,c马原地不动 此时c马以及落后太多了,所以c马得到了先跑权力。 直到我们交出了10此跑步的权力之后,结束竞争。(力友: 白痴白痴白痴)

参考链接:

https://leetcode-cn.com/problems/chou-shu-lcof/solution/mian-shi-ti-49-chou-shu-dong-tai-gui-hua-qing-xi-t/

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: