49_UglyNumber

package pers.lyt.java;

//题目:丑数
//	把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。
//例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做第一个丑数。
//  习惯上我们把1当做是第一个丑数。1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24。
public class Offer49_UglyNumber {
	/**
	 * 解法一:逐个判断每个整数是不是丑数的解法,直观但不够高效(暴力法)
	 */
	public int getUglyNumber_Solution1(int index) {
		if (index <= 0)
			return 0;

		int number = 0;
		int uglyFound = 0; // 表示第几个丑数

		while (uglyFound < index) {
			number++;
			if (isUgly(number)) {
				uglyFound++;
			}
		}
		return number;
	}

	public boolean isUgly(int number) {
		while (number % 2 == 0)
			number = number / 2;
		while (number % 3 == 0)
			number = number / 3;
		while (number % 5 == 0)
			number = number / 5;

		return number == 1;
	}

	/**
	 * 解法二:空间换时间,利用一个数组来保存前面已经找到的丑数,再依次得到后面的丑数,
	 * 这样就可以直接跳过那些不是丑数的数,不用每一个数都去判断。
	 * num1,num2,num3  min	mul2,mul3,mul5
	 * ugly[0]			1	0 0 0
	 * 2、3、5			2	1 0 0
	 * 4、3、5			3	1 1 0
	 * 4、6、5			4	2 1 0
	 * 6、6、5			5	2 1 1
	 * 6、6、10			6	3 2 1
	 * 8、9、10			8	4 2 1
	 */
	public int getUglyNumber_Solution2(int index) {
		if (index <= 0)
			return 0;

		int[] uglyArray = new int[index];
		uglyArray[0] = 1; // 第一个丑数默认为1

		int multiply2 = 0;
		int multiply3 = 0;
		int multiply5 = 0;

		for (int i = 1; i < index; i++) {
			int min = min(uglyArray[multiply2] * 2, uglyArray[multiply3] * 3, uglyArray[multiply5] * 5);
			uglyArray[i] = min;

			while (uglyArray[multiply2] * 2 == uglyArray[i]) {
				multiply2++;
			}
			while (uglyArray[multiply3] * 3 == uglyArray[i]) {
				multiply3++;
			}
			while (uglyArray[multiply5] * 5 == uglyArray[i]) {
				multiply5++;
			}
		}
		return uglyArray[index - 1];
	}
	
	/**
	 * 因为要保证丑数数组是从小到大排序的,每一个都要比较一下三个值,取最小值放入数组中,
	 * 然后再更新这个最小值。
	 */
	private int min(int number1, int number2, int number3) {
		int min = (number1 < number2) ? number1 : number2;
		return (min < number3) ? min : number3;
	}

	public static void main(String[] args) {
		Offer49_UglyNumber demo = new Offer49_UglyNumber();
		int number1 = demo.getUglyNumber_Solution1(1500);
		int number2 = demo.getUglyNumber_Solution2(1500);
		System.out.println(number1 + " " + number2);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值