您的位置:首页 > 其它

Lintcode 4 Ugly Number II

2018-03-08 20:40 225 查看
原题如下:

Ugly number is a number that only have factors 
2
3
 and 
5
.Design an algorithm to find the nth ugly number. The first 10 ugly numbers are 
1, 2, 3, 4, 5, 6, 8, 9, 10, 12...
 NoticeNote that 
1
 is typically treated as an ugly number.ExampleIf 
n=9
, return 
10
.题目的意思是看丑陋数,意思是只能被2,3,5相除的数,刚开始审题的时候没有看到题意中的only,一直卡在63%上,解题的方法很多,刚开始的做法是从一开始进行判断,直到n为止,但是这种方法十分耗时,因此会超时。附上代码如下:
public class Solution {

/**
* 求第N个丑数
* @param n
* @return 第N个丑数
*/
public int nthUglyNumber(int n) {

if (n <= 1) {
return 1;
}

int counter = 0;
for (int i = 1; ; i++) {

if (isUgly(i)) {
counter++;
if (counter == n) {
return i;
}
}
}
}

/**
* 判断数字是否为丑数
* @param num 被判断数字
* @return true:丑数,false:非丑数
*/
public boolean isUgly(int num) {

if (num <= 0) {
return false;
}

while (num % 2 == 0) num /= 2;
while (num % 3 == 0) num /= 3;
while (num % 5 == 0) num /= 5;

if (num == 1) {
return true;
} else {
return false;
}
}
}
后期加工的代码如下:
public class Solution {

/**
* 求第N个丑数
* @param n
* @return 第N个丑数
*/
public int nthUglyNumber(int n) {

int[] uglyNumbers = new int
;
uglyNumbers[0] = 1;

int idx2 = 0;
int idx3 = 0;
int idx5 = 0;

int counter = 1;
while (counter < n) {
int min = minOf(
uglyNumbers[idx2] * 2,
uglyNumbers[idx3] * 3,
uglyNumbers[idx5] * 5);
if (min == uglyNumbers[idx2] * 2) {
idx2++;
}
if (min == uglyNumbers[idx3] * 3) {
idx3++;
}
if (min == uglyNumbers[idx5] * 5) {
idx5++;
}
uglyNumbers[counter] = min;
counter++;
}
return uglyNumbers[n - 1];
}

/**
* 求三个数字中最小的数字
* @param a 数字a
* @param b 数字b
* @param c 数字c
* @return a、b、c中最小的数字
*/
private int minOf(int a, int b, int c) {
int temp = a < b ? a : b;
return temp < c ? temp : c;
}
}
为了方便理解这段代码,在这段代码里加入了System.out.println函数用于将结果输出到控制台。解除这些注释行,并指定输入的n为15,执行函数时输出到控制台的结果如下:
uglyNumbers[0]:1
-----------
idx2:0;ugly[idx2]:1
idx3:0;ugly[idx3]:1
idx5:0;ugly[idx5]:1
idx2:0;idx3:0;idx5:0
min==ugly[idx2]*2:2
idx2:0→1
uglyNumbers[1]:2
-----------
idx2:1;ugly[idx2]:2
idx3:0;ugly[idx3]:1
idx5:0;ugly[idx5]:1
idx2:1;idx3:0;idx5:0
min==ugly[idx3]*3:3
idx3:0→1
uglyNumbers[2]:3
-----------
idx2:1;ugly[idx2]:2
idx3:1;ugly[idx3]:2
idx5:0;ugly[idx5]:1
idx2:1;idx3:1;idx5:0
min==ugly[idx2]*2:4
idx2:1→2
uglyNumbers[3]:4
-----------
idx2:2;ugly[idx2]:3
idx3:1;ugly[idx3]:2
idx5:0;ugly[idx5]:1
idx2:2;idx3:1;idx5:0
min==ugly[idx5]*5:5
idx5:0→1
uglyNumbers[4]:5
-----------
idx2:2;ugly[idx2]:3
idx3:1;ugly[idx3]:2
idx5:1;ugly[idx5]:2
idx2:2;idx3:1;idx5:1
min==ugly[idx2]*2:6
idx2:2→3
min==ugly[idx3]*3:6
idx3:1→2
uglyNumbers[5]:6
-----------
idx2:3;ugly[idx2]:4
idx3:2;ugly[idx3]:3
idx5:1;ugly[idx5]:2
idx2:3;idx3:2;idx5:1
min==ugly[idx2]*2:8
idx2:3→4
uglyNumbers[6]:8
-----------
idx2:4;ugly[idx2]:5
idx3:2;ugly[idx3]:3
idx5:1;ugly[idx5]:2
idx2:4;idx3:2;idx5:1
min==ugly[idx3]*3:9
idx3:2→3
uglyNumbers[7]:9
-----------
idx2:4;ugly[idx2]:5
idx3:3;ugly[idx3]:4
idx5:1;ugly[idx5]:2
idx2:4;idx3:3;idx5:1
min==ugly[idx2]*2:10
idx2:4→5
min==ugly[idx5]*5:10
idx5:1→2
uglyNumbers[8]:10
-----------
idx2:5;ugly[idx2]:6
idx3:3;ugly[idx3]:4
idx5:2;ugly[idx5]:3
idx2:5;idx3:3;idx5:2
min==ugly[idx2]*2:12
idx2:5→6
min==ugly[idx3]*3:12
idx3:3→4
uglyNumbers[9]:12
-----------
idx2:6;ugly[idx2]:8
idx3:4;ugly[idx3]:5
idx5:2;ugly[idx5]:3
idx2:6;idx3:4;idx5:2
min==ugly[idx3]*3:15
idx3:4→5
min==ugly[idx5]*5:15
idx5:2→3
uglyNumbers[10]:15
-----------
idx2:6;ugly[idx2]:8
idx3:5;ugly[idx3]:6
idx5:3;ugly[idx5]:4
idx2:6;idx3:5;idx5:3
min==ugly[idx2]*2:16
idx2:6→7
uglyNumbers[11]:16
-----------
idx2:7;ugly[idx2]:9
idx3:5;ugly[idx3]:6
idx5:3;ugly[idx5]:4
idx2:7;idx3:5;idx5:3
min==ugly[idx2]*2:18
idx2:7→8
min==ugly[idx3]*3:18
idx3:5→6
uglyNumbers[12]:18
-----------
idx2:8;ugly[idx2]:10
idx3:6;ugly[idx3]:8
idx5:3;ugly[idx5]:4
idx2:8;idx3:6;idx5:3
min==ugly[idx2]*2:20
idx2:8→9
min==ugly[idx5]*5:20
idx5:3→4
uglyNumbers[13]:20
-----------
idx2:9;ugly[idx2]:12
idx3:6;ugly[idx3]:8
idx5:4;ugly[idx5]:5
idx2:9;idx3:6;idx5:4
min==ugly[idx2]*2:24
idx2:9→10
min==ugly[idx3]*3:24
idx3:6→7
uglyNumbers[14]:24
-----------
return:24
摘抄网上大佬的其他方法:HashMap + PriorityQueue(MinHeap):将2,3,5入队,每次取出堆顶元素(最小值),依次和3个factor相乘,将所得结果入队。用HashMap记录入队元素,入过队的元素不能再次入队。
代码如下:HashMap + Heap O(nlogn):
class Solution {
/**
* @param n an integer
* @return the nth prime number as description.
*/
public int nthUglyNumber(int n) {
// Write your code here
//HashMap + Heap O(nlogn)

if(n <= 0){
return 0;
}

PriorityQueue<Long> Q = new PriorityQueue<Long>();
HashMap<Long, Boolean> inQ = new HashMap<Long, Boolean>();
Long[] prime = new Long[3];
prime[0] = Long.valueOf(2);
prime[1] = Long.valueOf(3);
prime[2] = Long.valueOf(5);
for(int i = 0; i < 3; i++){
Q.add(prime[i]);
inQ.put(prime[i], true);
}

//每次取最小堆(优先队列)顶的元素,取n-1次,同时将取出的数和3个factor相乘的结果加入队列(如果本来已经在队列中则不用加)
Long number = Long.valueOf(1);
for(int i = 1; i < n; i++){
number = Q.poll();
for(int j = 0; j < 3; j++){
if(!inQ.containsKey(number * prime[j])){
Q.add(number * prime[j]);
inQ.put(number * prime[j], true);
}
}
}
//Long转换为Int
return number.intValue();
}
}
另有简便方法:class Solution {
public:
    int nthUglyNumber(int n) {
        vector<int> res(1, 1);
        int i2 = 0, i3 = 0, i5 = 0;
        while (res.size() < n) {
            int m2 = res[i2] * 2, m3 = res[i3] * 3, m5 = res[i5] * 5;
            int mn = min(m2, min(m3, m5));
            if (mn == m2) ++i2;
            if (mn == m3) ++i3;
            if (mn == m5) ++i5;
            res.push_back(mn);
        }
        return res.back();
    }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: