面试题49_丑数

2020-02-21  本文已影响0人  shenghaishxt

题目描述

我们把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

题解一

第一种方法是逐个数字判断是不是丑数。

判断某个数字是否为丑数的思想很简单,根据丑数的定义,丑数只能被2、3或5整除。因此不断将这个数字除以2、3或5,如果最后结果为1,则说明这个数是丑数;如果不能被整除,则说明不是丑数。

时间复杂度为O(n^2),空间复杂度为O(1)。

public int GetUglyNumber_Solution(int index) {
    int count = 0, num = 1;
    while (true){
        if (isUgly(num))
            count++;
        if (count == index)
            return num;
        num++;
    }
}

private boolean isUgly(int num) {
    if (num == 1)
        return true;
    while (num > 1) {
        if (num % 2 == 0) num /= 2;
        else if (num % 3 == 0) num /= 3;
        else if (num % 5 == 0) num /= 5;
        else return false;
    }
    return num == 1;
}

题解二

我们可以创建数组保存已找到的丑数,根据丑数的定义,丑数应该是另一个丑数乘上2、3或5的结果,所以我们用一个数组保存排序好的丑数,每个丑数都是由前面的丑数乘上2、3或5得到的。

为了按序保存丑数,创建三个队列,用于保存丑数分别乘以2、3或5的结果。由于队列先进先出的特性,因此队列中的丑数也是排好序的,所以每次都将三个队列的队头进行比较,将较小值存入数组中,然后再将队头删除。

时间复杂度为O(n),空间复杂度为O(n)。

public int GetUglyNumber_Solution(int index) {
    if (index == 0)
        return 0;
    Stack<Integer> stack = new Stack<>();
    int min = 1;
    stack.add(min);
    Queue<Integer> queue2 = new LinkedList<>();
    Queue<Integer> queue3 = new LinkedList<>();
    Queue<Integer> queue5 = new LinkedList<>();

    while (stack.size() < index) {
        queue2.offer(min * 2);
        queue3.offer(min * 3);
        queue5.offer(min * 5);

        int val2 = queue2.isEmpty() ? Integer.MAX_VALUE : queue2.peek();
        int val3 = queue3.isEmpty() ? Integer.MAX_VALUE : queue3.peek();
        int val5 = queue5.isEmpty() ? Integer.MAX_VALUE : queue5.peek();

        min = Math.min(Math.min(val2, val3), val5);
        stack.add(min);
        if (min == val2) queue2.poll();
        if (min == val3) queue3.poll();
        if (min == val5) queue5.poll();
    }
    return stack.peek();
}
上一篇 下一篇

猜你喜欢

热点阅读