剑指offer_丑数

题目:

把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

解题思路:

参考程序员面试金典P190

每次将第n个丑数A存入列表时,利用其他三个列表Q2,Q3,Q5分别存储A*2,A*3,A*5.
找出三个列表中最小的元素,将它作为下一个丑数。
重复上述操作,直至找到第K个丑数。

优化在于:
当找出的丑数A位于Q2时,列表Q2,Q3,Q5分别存储A*2,A*3,A*5.
当找出的丑数A位于Q3时,只需列表Q3,Q5分别存储A*3,A*5.
(ps:因为A位于Q3,故能找到B满足A=3*B,若将A*2放入Q2,即2*3*B放入Q2,而2*3*B在Q3中已被处理过。这个过程可以简单的罗列下前几个元素,就可以看出)
当找出的丑数A位于Q5时,只需列表Q5存储A*5.

这个方法算优解了,稍微带点空间换时间的概率,但空间也在优化。不是无脑的上来直接把A*2,A*3,A*5全放到队列里,每次检索最小值,放到丑数队列中去。
在网上看到更牛逼的代码,没有辅助队列,只有三个辅助变量
直接上代码,简单到一点都不想解释

public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if(index<1){
            return 0;
        }
        int[] array = new int[index];
        int i2=0;
        int i3=0;
        int i5=0;
        array[0]=1;
        for(int i =0;i<index-1;i++){
            int temp = getMin(array[i2]*2,array[i3]*3,array[i5]*5);
            if(temp==array[i2]*2){
                i2++;
            }
            if(temp==array[i3]*3){
                i3++;
            }
            if(temp==array[i5]*5){
                i5++;
            }
            array[i+1]=temp;
        }
        return array[index-1];
    }

    public int getMin(int a,int b,int c){
        int min = a;
        if(a>b){
            min=b;
        }
        if(min>c){
            min=c;
        }
        return min;
    }
}
posted on 2016-10-05 09:22  gerhold123  阅读(129)  评论(0编辑  收藏  举报