參考博客:http://www.cnblogs.com/grandyang/p/4743837.html
根絕題目提示,無須每個整數都判斷一下是否是醜數,因爲大部分的數都不是醜數,
所以只關注那些醜數是如何遞歸構造的就可以了,後面的醜數都是前面的醜數*2或
*3或*5所得的,即nextUgly = kthUgly * (2 | 3 |5)。
現在只要正確地把這些醜數排好序就可以了。可以用歸併排序的思路,
有三個子序列,分別是醜數*2,醜數*3,醜數*5的子序列,現在只需要把這三個子序列
合併成一個序列就好了。重點還要注意不能重複(所有遇到符合醜數的子序列都要更新下標指向),畫一個表格就清楚了。
i2 |
i3 |
i5 |
m2 |
m3 |
m5 |
mn |
resultVec |
0 |
0 |
0 |
2 |
3 |
5 |
2 |
1,2 |
1 |
0 |
0 |
4 |
3 |
5 |
3 |
1,2,3 |
1 |
1 |
0 |
4 |
6 |
5 |
4 |
1,2,3,4 |
2 |
1 |
0 |
6 |
6 |
5 |
5 |
1,2,3,4,5 |
2 |
1 |
1 |
6 |
6 |
10 |
6 |
1,2,3,4,5,6 |
… |
… |
… |
… |
… |
… |
… |
… |
i2,i3,i5是resultVec的下標,m2,m3,m5分別是從三個子序列求得的值,mn是下一個加進resultVec的醜數
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> resultVec;
resultVec.push_back(1);
int ind2 = 0, ind3 = 0, ind5 = 0;
while (resultVec.size() < n) {
int nextUgly = min(resultVec[ind2], min(resultVec[ind3], resultVec[ind5]));
resultVec.push_back(nextUgly);
if (nextUgly == resultVec[ind2]) {
ind2++;
}
if (nextUgly == resultVec[ind3]) {
ind3++;
}
if (nextUgly == resultVec[ind5]) {
ind5++;
}
}
return resultVec[n - 1];
}
};