第二种方法在http://www.nowcoder.com/practice/6aa9e04fc3794f68acf8778237ba065b?rp=2&ru=/ta/coding-interviews已通过测试,第一种超时,所以细节错误不确定。
方法1:
遍历:
<span style="font-size:14px;">public class Solution {
public int GetUglyNumber_Solution(int index) {
int uglyNum = 0;
int i;
for(i = 1;uglyNum < index; i++){
if(isUgly(i)){
uglyNum++;
}
}
return --i;
}
public boolean isUgly(int num){
while(num%2 == 0){
num /= 2;
}
while(num%3 == 0){
num /= 3;
}
while(num%5 == 0){
num /= 5;
}
return num==1?true:false;
}
}</span>
方法2:
<span style="font-size:14px;">public class Solution {
public int GetUglyNumber_Solution(int index) {
if(index <= 0)
return 0;
int[] ugly = new int[index];
ugly[0] = 1;
int index1 = 1;
int index2 = 0;
int index3 = 0;
int index4 = 0;
while(index1 < index){
int minNum = Min(ugly[index2] * 2 , ugly[index3] * 3 , ugly[index4] *5);
if(minNum == ugly[index2]*2)
index2++;
if(minNum == ugly[index3]*3)
index3++;
if(minNum == ugly[index4]*5)
index4++;
ugly[index1++] = minNum;
}
return ugly[index-1];
}
int Min (int one,int two,int three){
int temp = one>two?two:one;
return temp>three?three:temp;
}
} </span>
第二种方法用了空间换时间的方法,增大了内存但是节省了效率。思路基本是:每个丑数都是由别的丑数乘2/3/5来的,所以把所有的丑数存储,记住前面的下表,一旦前面那个数的乘2/3/5的丑数已经被后边使用,就把相应的下表向前移动一个。
不善文笔,可以看http://blog.csdn.net/coder_xia/article/details/6707600这篇文章,他讲的比较容易理解。