丑数
思路:定义三个队列,三个队列的头指针为t2,t3,t5, t2表示乘2的队列,t3表示乘3的队列,t5表示乘5的队列,每次选出最小的队列头,并弹出该队列头,弹出时把该最小值分别乘以2,3,5放入相应的队列,继续求出最小的队列头。
1.为什么分三个队列?
丑数数组里的数一定是有序的,因为我们是从丑数数组里的数乘以2,3,5选出的最小数,一定比以前未乘以2,3,5大,同时对于三个队列内部,按先后顺序乘以2,3,5分别放入,所以同一个队列内部也是有序的;
2.为什么比较三个队列头部最小的数放入丑数数组?
因为三个队列是有序的,所以取出三个头中最小的,等同于找到了三个队列所有数中最小的。
实现思路:
我们没有必要维护三个队列,只需要记录三个指针显示到达哪一步;“|”表示指针,arr表示丑数数组;
(1)1
|2
|3
|5
目前指针指向0,0,0,队列头arr[0] * 2 = 2, arr[0] * 3 = 3, arr[0] * 5 = 5
(2)1 2
2 |4
|3 6
|5 10
目前指针指向1,0,0,队列头arr[1] * 2 = 4, arr[0] * 3 = 3, arr[0] * 5 = 5
(3)1 2 3
2| 4 6
3 |6 9
|5 10 15
目前指针指向1,1,0,队列头arr[1] * 2 = 4, arr[1] * 3 = 6, arr[0] * 5 = 5
………………
class Solution { public: int GetUglyNumber_Solution(int index) { if(index<7) return index; vector<int> res(index); res[0]=1; int t2=0,t3=0,t5=0; for(int i=1;i<index;++i) { res[i]=min(res[t2]*2,min(res[t3]*3,res[t5]*5)); if(res[i]==res[t2]*2) ++t2; if(res[i]==res[t3]*3) ++t3; if(res[i]==res[t5]*5) ++t5; } return res[index-1]; } };