[Sword refers to offer] 49. Ugly number

Title description

Insert picture description here
Insert picture description here

// 力扣
// 我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求
// 按从小到大的顺序的第 n 个丑数。

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

answer

///

// 由题意可知,丑数n因子包括2 3 5,如果一个数能被2,3,5整除,那么连续将
// 其因子2,3,5除尽后(while (n%2 == 0): n = n/2...)得到的数为1。
// 这个数n就是丑数。我们大可以从1开始一个个判断每个整数是不是丑数

// 但是这样做效率太低了。
// 由于丑数因子相同,所以小丑数 × 2/3/5可以得到大丑数,这就可以用一个
// 数组存储丑数,利用动态规划使得我们从小丑数推断出大丑数。
// 注意要维持数组从小到大的性质。


// 力扣
// 执行用时: 2 ms, 在所有 Java 提交中击败了99.11% 的用户
// 内存消耗:37.3 MB, 在所有 Java 提交中击败了93.79%的用户
class Solution {
    public int nthUglyNumber(int n) {
		// for循环用于递归丑数数组的每一个位置,将该位置对应
		// 的丑数从小到大推断出来。由于丑数只包含2 3 5这三个因子,
		// 我们根据前面的小丑数,分别乘这三个因子就可以得到后面的大丑数,
		// i2,i3,i5用于前面“小丑数”的索引,dp[i2]用于乘2,dp[i3]用于乘3,
		// dp[i5]用于乘5,索引均初始化为0(数组第一位),
		// 由于要分别乘3个因子,所以会得到3个丑数,又因为需要升序,
		// 所以取乘出的三个丑数中最小的丑数作为当前遍历位置丑数即可。
		// 此时参加推断的索引右移一位。
		
		// 注意:再次强调,丑数的因子只有2,3,5,
		// 我们设置i2,i3,i5这三个索引从0开始右移,
		// 专门用于遍历索引乘2,3,5。也就是说所有的“小丑数”
		// 都有机会被i2,i3,i5遍历并乘2 3 5中的任意一个,来推导下一个丑数
		// 所以这个过程,就足以包含所有小丑数,推导出大丑数的所有情况(三种乘法)
        int i2 = 0, i3 = 0, i5 = 0;
		// 构建长度为n的数组,推断出的第n个元素(尾元素)就是我们要的元素
		int[] dp = new int[n];
		// 数组第一个丑数为1
		dp[0] = 1;
		for (int i = 1; i < n; i++) {
			int b2 = dp[i2] * 2, b3 = dp[i3] * 3, b5 = dp[i5] * 5;
			dp[i] = Math.min(b2, Math.min(b3, b5));
			if (dp[i] == b2)
				i2++;
			if (dp[i] == b3)
				i3++;
			if (dp[i] == b5)
				i5++;
		}
		return dp[n - 1];
    }
}

// 牛客
// 运行时间:11ms,超过88.19%用Java提交的代码
// 占用内存:9584KB,超过71.92%用Java提交的代码
public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if (index == 0)
            return 0;
        int[] dp = new int[index];
        dp[0] = 1;
        int i2 = 0, i3 = 0, i5 = 0;
        for (int i = 1; i < index; i++) {
            int b2 = dp[i2] * 2, b3 = dp[i3] * 3, b5 = dp[i5] * 5;
            dp[i] = Math.min(b2, Math.min(b3, b5));
            if (dp[i] == b2)
                i2++;
            if (dp[i] == b3)
                i3++;
            if (dp[i] == b5)
                i5++;
        }
        return dp[index - 1];
    }
}

Guess you like

Origin blog.csdn.net/fisherish/article/details/113761841