【九度OJ1214】|【劍指offer34】醜數

題目描述:

把只包含因子二、3和5的數稱做醜數(Ugly Number)。例如六、8都是醜數,但14不是,由於它包含因子7。
習慣上咱們把1當作是第一個醜數。求按從小到大的順序的第N個醜數。 html

輸入:

輸入包括一個整數N(1<=N<=1500)。 java

輸出:

可能有多組測試數據,對於每組數據,
輸出第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 測試

方法二 spa

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) code

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 的結果。所以咱們能夠先找到已知數組裏的醜數乘以二、三、5獲得的第一個大於已知最大丑數的值,而後比較這三個值,最小的那個即爲要求得的醜數。

    這種算法不須要在非醜數的整數上作任何計算,所以時間複雜度要低不少。 htm

相關文章
相關標籤/搜索