面试题34:丑数

标签: 剑指offer


题目描述
只包含因子2,3,5的数称为丑数,1是第一个丑数,求第n个丑数是什么。

思路:
1 . 暴力法
  从1开始遍历每个整数,判断每个数是不是丑数,是的话计数器加1,当计数器等于n时,返回当前遍历到的整数。这种算法要计算1到第n个丑数中间的所有数。

// 判断一个数是否为丑数
public boolean isUgly(int number){
    while(number % 2 == 0) number /= 2;
    while(number % 3 == 0) number /= 3;
    while(number % 5 == 0) number /= 5;
    return (number == 1) ? true : false;
}

// 计算第n个丑数
public int getNthUglyNumber(int n){
    if(n <= 0) return 0;
    int number = 0;
    int count = 0;
    
    while(count < n){
        number++;
        if(isUgly(number)) count++;
    }
    
    return number;
}

2 . 空间换时间法
  使用数组存储1开始的所有丑数,每次根据已有丑数计算下一个丑数,并加到数组中,直到n个丑数全部算出来。
  这种算法只需要计算每一个丑数,忽略掉不是丑数的数,比第一种思路好,但是需要n的空间。
  丑数生成规则,由已有丑数x2,x3,x5中选取一个最小值作为下一个丑数。这里t2,t3,t5是能生成最新丑数的已有丑数下标,需要不断更新。

public int getNthUglyNumber(int n){
    if(n <= 0) return 0;
    int [] uglys = new int[n];
    uglys[0] = 1;
    int pCurr = 0;
    int t2 = 0; t3 = 0; t5 = 0;
    while(pCurr < n){
        int curr = min(uglys[t2] * 2, uglys[t3] * 3, uglys[t5] * 5);
        uglys[pCurr] = curr;
        while(uglys[t2] * 2 <= curr) t2++;
        while(uglys[t3] * 3 <= curr) t3++;
        while(uglys[t5] * 5 <= curr) t5++;
        pCurr++;
    }
    int result = uglys[n - 1];
    return result;
}
原文地址:https://www.cnblogs.com/banyu/p/6719131.html