丑数~~~~

把只包含因子2、3和5的数称作丑数,例如6是丑数,但14不是,因为它包含因子7,习惯上我们把1当作第一个丑数,求按从小到大的顺序的第N个丑数。
输入描述:整数N
输出描述:第N个丑数
第一种方法:遍历每一个整数i,若i能被2或者3或者5整除,count++,直到count = N时跳出循环,打印i

import java.util.Scanner;

public class KthUgly {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int count = 0;
		int i;
		for (i = 1; ; i++) {
			if(isUgly(i))
				count++;
			if(count == n)
				break;
		}
		System.out.println(i);
	}
	private static boolean isUgly(int n){
		while(n%2 == 0)
			n = n/2;
		while(n%3 == 0)
			n = n/3;
		while(n%5 == 0)
			n = n/5;
		if(n == 1){
			return true;
		}
		return false;
	}
}

但是第一种方法效率不高,不仅要计算丑数,还要考虑非丑数。所以产生了改进的方法:只考虑丑数。下一个丑数是该丑数前面的丑数分别乘以2、3、5中最小的那个数。例如现有丑数序列为1下一个丑数要在12,13,15中选择最小且大于当前丑数的12,现在的丑数序列变成了1,2.下一个丑数要在13,15,22,23,25中选择最小其大于当前丑数的13,现在序列变成了1,2,3。下一个丑数要在15,22,23,25,32,33,35中选择最小且大于当前丑数的22…用一个数组顺序存储每一个丑数

import java.util.Scanner;

public class KthUgly {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		System.out.println(getKthUgly(n));
		
	}
	private static int getKthUgly(int n){
		if(n == 0)
			return 0;
		int[] ugly = new int[n];
		int count = 1;
		ugly[0] = 1;
		int index2 = 0;
		int index3 = 0;
		int index5 = 0;
		while(count < n){
			int min = getMin(ugly[index2]*2, ugly[index3]*3, ugly[index5] *5);
			ugly[count] = min;
			while(ugly[index2] * 2 <= ugly[count]) index2++;
			while(ugly[index3] * 3 <= ugly[count]) index3++;
			while(ugly[index5] * 5 <= ugly[count]) index5++;
			count++;
		}
		return ugly[n-1];
	}
	private static int getMin(int a, int b, int c){
		return a>b?(b>c?c:b):(a>c?c:a);
	}
}

但是对于此题我有一个很疑惑的点:

因子的定义是假如整数n除以m,结果是无余数的整数,那么我们称m就是n的因子。
丑数的定义是因子只包含2、3、5的数。

以此看来以上两个解法是不对的,因为按照代码可以得出8是丑数,但是根据因子的定义8的因子还包括4,所以8不是丑数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值