Day33:丑数

时间:2022-07-24
本文章向大家介绍Day33:丑数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

剑指Offer_编程题——丑数

题目描述:

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

具体要求:

时间限制: C/C++ 1秒,其他语言2秒 空间限制: C/C++32M,其他语言64M

具体思路:

  最直接的暴力解法是从1开始依次判断数字是否为丑数,直到达到要求的丑数个数。当然这种方法肯定是会TLE的,所以我们分析一下丑数的生成特点(这里把1排除):因为丑数只包含质因子2,3,5,假设我们已经有n-1个丑数,按照顺序排列,且第n-1的丑数为M。那么第n个丑数一定是由这n-1个丑数分别乘以2,3,5,得到的所有大于M的结果中,最小的那个数。事实上我们不需要每次都计算前面所有丑数乘以2,3,5的结果,然后再比较大小。因为在已存在的丑数中,一定存在某个数T2,在它之前的所有数乘以2都小于已有丑数,而T2*2的结果一定大于M,同理,也存在这样的数T3,T5,我们只需要标记这三个数即可。我们可以按照以上思路执行一遍。具体过程如下:

具体我们用java和python将其实现。首先我们用java实现。

public class Solution{
	public int GetUglyNumber_Solution(int index){
		if(index <= 6)
			return index;
		int [] dp = new int[index];
		int i2 = 0;
		int i3 = 0;
		int i5 = 0;
		dp[0] = 1;
		for(int i = 1; i < index; i++){
			int next2 = dp[i2] * 2;
			int next3 = dp[i3] * 3;
			int next5 = dp[i5] * 5;
			dp[i] = Math.min(next2, Math.min(next3, next5));
			if(dp[i] == next2)
				i2++;
			if(dp[i] == next3)
				i3++;
			if(dp[i] == next5)
				i5++;
		}
		return dp[index - 1];
	}
}

代码效果图如图所示:

接下来我们用python将其实现

class Solution:
	def GetUglyNumber_Solution(self, index):
		if index == 0:
			return 0
		baseList = [1]
		min2 = min3 = min5 = 0
		curNum = 1
		while curNum < index:
			minNum = min(baseList[min2]*2, baseList[min3]*3, baseList[min5]*5)
			baseList.append(minNum)
			while baseList[min2] * 2 <= minNum:
				min2 += 1
			while baseList[min3] * 3 <= minNum:
				min3 += 1
			while baseList[min5] * 5 <= minNum:
				min5 += 1
			curNum += 1
		return baseList[-1]

代码效果图如图所示:

总结

  本道题主要是通过新概念考察穷举法,此题比较简单,很容易想到思路,但是如果直接暴力算法,可能反而通不过,由于执行时间过长。占用内存空间过多,因此,需要我们优化其算法思路,并且通过了java和python将其实现,优化过后发现其时间复杂度很低的。空间占用也很少的。因此,我们在做题的时候,应该多次尝试各种方法,扩展自己的思维,写出优质的代码。总之,我们要继续加油,争取早日找到工作,Good Luck!!!

参考文献

[1] 一颗随风而倒的墙头草 [2] IDEA_TEYU_1112