week8
题目
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.
原题地址 : https://leetcode.com/problems/ugly-number-ii/description/
解析
ugly number是分解为质数相乘形式中质数只包含2,3,5的数,要求第n大的ugly number(1属于ugly number)。
如果从1到无穷依次检测每个数是否为ugly number直到找到n个,可以解决问题但是所花的代价很大,会超时。
另一种思路是ugly number都可表示为(2^a)* (3^b) *(5^c)的形式,其中a,b,c为自然数。
先看下面代码:
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> v;
v.push_back(1);
if (n == 1) {
return 1;
}
else {
int a = 0, b = 0, c = 0;
while (1) {
v.push_back(min(v[a] * 2, v[b] * 3, v[c] * 5));
if (v.size() == n) {
return v.back();
}
if (v.back() == v[a] * 2) {
++a;
}
if (v.back() == v[b] * 3) {
++b;
}
if (v.back() == v[c] * 5) {
++c;
}
}
}
}
int min(int a, int b, int c) {
int result = a;
if (result > b) {
result = b;
}
if (result > c) {
result = c;
}
return result;
}
};
代码解析
取3个起指针作用的数(如a,b,c),起始都为0。数组(命名为v)起始只有元素1(第一个ugly number),后面的ugly number都是对前面已知的某个ugly number乘2或乘3或乘5得到,此时三个指针都指向v[0],因为v[a]*2=2,v[b] *3=3,v[c] *5=5,因此取2作为下一个ugly number,此时对能取得该ugly number的指针加1,即a。重复操作,考虑已知数组为1,2,3,此时a=1, v[a]=2 ; b=1, v[b]=2 ; c=0, v[c]=1,重复步骤,因为v[a] *2=4 , v[c] *5= 5,因此取4,加a。对能取得该ugly number的指针加1能防止如添加10(2 *5或5 *2)时只自增a或c而忽略另一个的问题。重复直至数组大小为n,此时数组最后一个元素即为所求。