java 找丑数_JAVA代码—算法基础:寻找丑数

寻找丑数

问题描述: 我们把只包含因子2、3和5的数称为丑数。例如6、8都是丑数,但是14不是,因为它包含因子7.

习惯上我们把1当作是第一个丑数。求按从小到大的顺序的第1500个丑数。

算法思路:

方法1 暴力求解

从1开始逐个遍历整数,每个整数如果包含2、3和5中的任何一个因子就除以该因子(包含多个就除以多个,直到不含2、3和5这三个因子),如果这样除得的结果为1,则表示只包含2、3和5,为丑数,此时丑数个数加1,直到个数为1500个。

缺点是:效率低,不管一个数是不是丑数都要作计算。

例如:第 1500 个丑数是 859963392,那么我们需要从 1 开始枚举到 859963392。

方法2

只计算丑数,后面的丑数根据前面的丑数和2、3、5来得出。

因为丑数的因子只有 2 3 或者 5,所以丑数必定是 某个丑数 k 的 2倍、3倍、或者 5倍。

这样我们就不需要从 1 开始枚举了到第 num 个丑数 target,我们可以根据得到丑数来推导出下一个丑数,这样大大节省了时间,接下来就是该如何去找到 这个 丑数 k 。

我们需要一个辅助数组 arr 来存储我们找到的丑数,最笨的方法当然是每次从数组的第一个开始找 k ,使得它的 2倍 3倍 或者 5倍 大于当前的数组最大值。

package com.bean.algorithmexec;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.util.Scanner;

public class UglyNumberDemo {

/* * 把只包含因子2、3和5的数称作丑数(Ugly Number)。 * 例如6、8都是丑数,但14不是,因为它包含因子7。 * 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 * */

/* * 思路分析: * 丑数应该是另一个丑数乘以2、3、5得到的。也就是说,根据一个丑数,可以计算出它乘以2、3、5得到的丑数。 * 因此,可以初始化一个数组numberArray,用于保存已经找到的丑数。 * 然后按序用数组里的数,乘以2、3、5得到新的丑数,并加入到数组中。 * * 首先将第一个丑数1加入的数组中。 * 然后计算1*2、1*3、1*5的最小值,并把最小值加入到数组中。 * 显然,1*2得到的值最小,所以把2加入到数组中。 * 当前数组为[1、2]。 * 因为这个2是由1*2计算得到的,所以下一次计算时,就不能再计算1*2了,不然2始终是最小值。 * 下一次应该计算2*2。或者说,由于1已经乘过2了,还有3、5没有乘,所以不用再乘2了,因为1不能多次乘2,以免得到重复的2。 * */

public static int getUglyNumber(int n) {

if(n <= 0) return 0;

int[] numberArray = new int[n];

numberArray[0] = 1;

int i = 0, j = 0, k = 0; // 分别代表2,3,5的下标

for(int a = 1; a < n; a++) {

int p = numberArray[i] << 1;

int q = numberArray[j] * 3;

int r = numberArray[k] * 5;

int min = Math.min(p, Math.min(q, r));

numberArray[a] = min;

if(p == min) {

i++;

}

if(q == min) {

j++;

}

if(r == min) {

k++;

}

}

return numberArray[n-1];

}

/* * 笨办法 * */

public static int getChouShu(int n){

int number=0;

int findCount=0;//已找到丑数的个数

while(findCount

int i=++number;

while(i%2==0){

i/=2;

}

while(i%3==0){

i/=3;

}

while(i%5==0){

i/=5;

}

if(i==1){

findCount++;

}

}

return number;//返回第n个丑数number

}

public static void main(String[] args) throws FileNotFoundException {

// TODO Auto-generated method stub

System.setIn(new FileInputStream("G:\\uglynumber.txt"));

Scanner sc = new Scanner(System.in);

while(sc.hasNextLine()) {

int N=sc.nextInt();

// int ANSWER = getUglyNumber(N);

int ANSWER = getChouShu(N);

System.out.println("第 "+N+" 个 Ugly Number是: "+ ANSWER);

}

}

}

(完)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值