标签:ret 数组 nlogn 思路 vector merge 复杂度 想法 优先队列
第一想法是建立一个足够大的bool数组,i遍历,如果nums[i]是ugly num,那么 2*nums[i] 3*nums[i] 5*nums[i] 一定也是 ugly num。最后遍历一遍找到第n个,但是这样空间会超,不行。
继续这个思路,可以利用一个优先队列,重复元素直接过掉,可以AC。但是时间复杂度要 O(nlogn)。
class Solution { public: int nthUglyNumber(int n) { priority_queue<long,vector<long>,greater<long>> q; q.push(1); long prev=0, cur; while (true){ while (q.top()==prev){ q.pop(); } cur = q.top(); q.pop(); //cout << cur << endl; --n; if (n==0) return cur; q.push(cur*2); q.push(cur*3); q.push(cur*5); prev = cur; } } };
可以利用类似 merge sort 的思路,依次比较三个头上的元素,需要注意的是,重复的元素的坐标都要向后,例如 如果最小元素是6,那么2*3和3*2都要向后。
1*2 2*2 3*2 ... ugly[i]*2 ...
1*3 2*3 3*3 ... ugly[i]*3 ...
1*5 2*5 3*5 ... ugly[i]*5 ...
class Solution { public: int nthUglyNumber(int n) { vector<int> ugly({1}); int i2, i3, i5; i2 = i3 = i5 = 0; for (int i=0;i<n-1;++i){ int x=min(ugly[i2]*2,min(ugly[i3]*3,ugly[i5]*5)); ugly.push_back(x); if (x==ugly[i2]*2) ++i2; if (x==ugly[i3]*3) ++i3; if (x==ugly[i5]*5) ++i5; } return ugly.back(); } };
标签:ret 数组 nlogn 思路 vector merge 复杂度 想法 优先队列
原文地址:https://www.cnblogs.com/hankunyan/p/9533278.html