剑指offer:面试题49:丑数

题目

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

思路

  • 思路一,逐一判断每个数字是否是丑数,直到找到第k个丑数
  • 思路二,上述思路需要判断每个数字,计算量大。因此思路二提出利用空间换时间的思路。即将已经排序好丑数存在一个数组中,之后的每个丑数都由这个数组中的丑数2或者3或者5得到。
    关键在于,如何将这些丑数排序?可以从数组中找到3个丑数T2,T3,T5,这3个丑数满足,T2
    2,T33,T55都刚好比数组中最大的丑数大,则min(T22,T33,T5*5)就是下一个丑数,并存入数组。同时更新T2,T3,T5,使得仍满足上述条件。

测试用例

1.功能测试(2,3,4,5等)
2.特殊测试(0,1)
3…性能测试(1500等)

Java实现

实现一

import java.util.ArrayList;

public class GetUglyNumber_Solution {
        public int GetUglyNumber_Solution(int index) {
        if (index <= 0) return 0;
        int number = 0;
        int uglyCount = 0;
        while (uglyCount < index) {
            number++;
            if (isUglyNumber(number)) {
                uglyCount++;
            }
        }
        return number;
    }

    /**
     * 判断是否是丑数
     * @param num
     * @return
     */
    public boolean isUglyNumber(int num) {
        while (num % 2 == 0) {
            num /= 2;
        }
        while (num % 3 == 0) {
            num /= 3;
        }
        while (num % 5 == 0) {
            num /= 5;
        }
        return  num == 1;
    }


    public static void main(String[] args) {
        GetUglyNumber_Solution ugly = new GetUglyNumber_Solution();
        int re = ugly.GetUglyNumber_Solution(8);
        System.out.println(re);
    }
}

实现二

import java.util.ArrayList;

public class GetUglyNumber_Solution {
    public int GetUglyNumber_Solution(int index) {
        if (index <= 0) return 0;
        int number = 0;
        ArrayList<Integer> uglyNumList = new ArrayList<>();
        uglyNumList.add(1);
        ArrayList<Integer> uglyNumList2 = uglyNumList;
        ArrayList<Integer> uglyNumList3 = uglyNumList;
        ArrayList<Integer> uglyNumList5 = uglyNumList;
        number++;
        int index2 = 0, index3 = 0, index5 = 0;
        while (number < index) {
            int min = minMulti(uglyNumList2.get(index2) * 2, uglyNumList3.get(index3) * 3, uglyNumList5.get(index5) * 5);
            uglyNumList.add(min);
            while (uglyNumList2.get(index2) * 2 <= uglyNumList.get(number)) {
                index2++;
            }
            while (uglyNumList3.get(index3) * 3 <= uglyNumList.get(number)) {
                index3++;
            }
            while (uglyNumList5.get(index5) * 5 <= uglyNumList.get(number)) {
                index5++;
            }
            number++;
        }

        return uglyNumList.get(index - 1);
    }

    public int minMulti(int a, int b, int c) {
        int min = (a < b) ? a : b;
        min = (min < c) ? min : c;
        return min;
    }

    public static void main(String[] args) {
        GetUglyNumber_Solution ugly = new GetUglyNumber_Solution();
        int re = ugly.GetUglyNumber_Solution(8);
        System.out.println(re);
    }
}

收获

利用丑数性质,在消耗有限空间下,大大减少时间消耗。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值