您的位置:首页 > Web前端

【九度OJ1214】|【剑指offer34】丑数

2013-10-16 00:00 309 查看
题目描述:
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

输入:
输入包括一个整数N(1<=N<=1500)。

输出:
可能有多组测试数据,对于每组数据,
输出第N个丑数。

方法一:(粗糙啊)

import java.util.Scanner;

public class CopyOfMain {

public boolean isPrime(int number){
boolean flag = true;
for(int i = 2; i <= Math.sqrt(number); i++){
if(number % i == 0){
flag = false;
break;
}
}
return flag;
}
public boolean isUgly(int number){
if(isPrime(number)){
if(number == 2 || number == 3 || number == 5 || number == 1)
return true;
else{
return false;
}
}
boolean flag = false;
for(int i = 2; i < Math.sqrt(number) + 1; i++){
int a = number % i;
if(a == 0){
flag = isUgly(i)&&isUgly(number/i);
}
}
return flag;
}
public void countUgly(int count){
if(count <= 6)
System.out.println(count);
else{
int j = 6;
int number = 7;
while(j < count){
if(isUgly(number++)){
j++;
}
}
System.out.println(number-1);
}
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
CopyOfMain m = new CopyOfMain();
m.countUgly(s.nextInt());
}

}

咋想的呢!硬生生的解,效率极低最后Runtimeout

方法二

import java.util.Scanner;

public class Copy_2_of_Main {

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;
}

public void countUgly(int count) {
int j = 0;
int number = 1;
while (j < count) {
if (isUgly(number++)) {
j++;
}
}
System.out.println(number - 1);
}

public static void main(String[] args) {
// Scanner s = new Scanner(System.in);
Copy_2_of_Main m = new Copy_2_of_Main();
// m.countUgly(s.nextInt());
for (int i = 1; i < 20; i++)
m.countUgly(i);
}

}
依然是效率问题会额外计算非丑数。
方法三:(参考http://www.cnblogs.com/mingzi/archive/2009/08/04/1538491.html)

import java.util.Scanner;

public class Main {

public void countUgly(int count) {
if(count <= 0)return;
int[] array = new int[count];
int pos = 0;
array[0] = 1;
int i = 0;
int j = 0;
int k = 0;
while (pos < count - 1) {
while (array[pos] >= array[i] * 2)
i++;
while (array[pos] >= array[j] * 3)
j++;
while (array[pos] >= array[k] * 5)
k++;
array[++pos] = Min(array[i] * 2, array[j] * 3, array[k] * 5);
}
System.out.println(array[pos]);
}

public int Min(int a, int b, int c) {
a = Math.min(a, b);
return Math.min(a, c);
}

public static void main(String[] args) {
Scanner s = new Scanner(System.in);
Main m = new Main();
while(s.hasNext())
m.countUgly(s.nextInt());
}

}
试图只计算丑数,而不在非丑数的整数上花费时间。根据丑数的定义,丑数应该是另一个丑数乘以
2

3
或者
5
的结果(
1
除外)。因此我们可以创建一个数组,里面的数字是排好序的丑数。里面的每一个丑数是前面的丑数乘以
2

3
或者
5
得到的。在已知一个数组大小的丑数序列时,下一个丑数必然大于已知的最大丑数,并且该丑数是由已知数组里的丑数
乘以
2

3
或者
5
的结果。因此我们可以先找到已知数组里的丑数乘以2、3、5得到的第一个大于已知最大丑数的值,然后比较这三个值,最小的那个即为要求得的丑数。
这种算法不需要在非丑数的整数上做任何计算,因此时间复杂度要低很多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息