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

题目描述:

把只包含因子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得到的第一个大于已知最大丑数的值,然后比较这三个值,最小的那个即为要求得的丑数。

    这种算法不需要在非丑数的整数上做任何计算,因此时间复杂度要低很多。


你可能感兴趣的:(java,丑数,九度OJ1511,剑指offer34)