丑数

思路:定义三个队列,三个队列的头指针为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];
    }
};

  

posted @ 2019-05-15 19:44  LJ的博客  阅读(193)  评论(0编辑  收藏  举报