算法设计Week17 LeetCode Algorithms Problem #264 Ugly Number II

来源:互联网 发布:当今世界网络强国 编辑:程序博客网 时间:2024/06/03 13:41

题目描述:

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

Note that 1 is typically treated as an ugly number, and n does not exceed 1690.


题目分析:

题目中提到的“ugly number”是指数字的质因数只有2,3,5组成。如果把所有的ugly number由小到大排成序列,就有:
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18 …
很容易能够发现,除了1,余下的所有数字都可以看做是前面的某一个数字乘以2,3或5得到的。那下一个数字必然是x * 2, y * 3, z * 5中较小的一个数字,而这里的x, y, z都是序列中已经存在的数字。
下面要解决的问题就是如何确定x, y, z了。
1. 假设x = 8; y =6; z = 4:
这时,x * 2 = 16, y * 3 = 18, z * 5 = 20。显然数列中下一个数应为16,这时,x取序列中下一个值,即x = 9。
2. 假设x = 3; y = 2; z = 2:
这时,x * 2 = 6, y * 3 = 6, z * 5 = 10。数列中下一个数应为6,这时,x和y都应该进行更新,分别取其对应的下一个值,即x = 4, y = 3。
下面,考虑x, y, z的初始值,显然,初始值选择1就可以了。


解题代码:

本题对应的代码如下,算法的时间复杂度为O(n),空间复杂度为O(n)

class Solution {public:    int nthUglyNumber(int n) {        if(n == 1) return 1;        vector<int> num(n,1);        int t2 = 0, t3 = 0, t5 = 0;        for(int i = 1; i < n; i++){            num[i] = min(num[t2] * 2, min(num[t3] * 3, num[t5] * 5));            if(num[i] == num[t2] * 2) ++t2;            if(num[i] == num[t3] * 3) ++t3;            if(num[i] == num[t5] * 5) ++t5;        }        return num.back();    }};