剑指offer : 丑数

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

由丑数的定义我们可以知道丑数都是由*{2,3,5}推导出来的

1*{2,3,5}得到{2,3,5}*{2,3,5}得到{4,6,10,6,9,10,10,15,25}

因此可以看到   单纯去乘得到的丑数数组是有重复的,要去重。

而且题目要求从小到大第N个树,这样得到的数组无序。

因此我们指定三个数组,每次将三个数组中最小的那个数插入丑数数组;

至于为什么是三个数组,因此丑数只包含三个质因子  2,3,5 。

所以用三个数组来保存乘之后的结果。

丑数数组:1         

乘 2:2

扫描二维码关注公众号,回复: 5896297 查看本文章

乘 3:3

乘 5 :5

丑数数组:1,2

乘 2:2,4

乘 3:3,6

乘 5:5,10

丑数数组:1,2,3

乘 2:4,6

乘 3:6,9

乘 5:10,15

这样的话,就会得到一个从小到大排列的丑数数组。

每次记录三个数组的最小值进行对比,将得到的最小的丑数插入丑数数组。

class Solution {
public:
	int GetUglyNumber_Solution(int index) 
	{
		if (index <= 0)
			return 0;
		vector<int> vec(index);
		vec[0] = 1;
		vec[1] = 2;
		vec[2] = 3;
		vec[3] = 4;
		vec[4] = 5;
		for (int i = 5; i < index; i++)
		{
			int min1 = 0;
			int min2 = 0;
			int min3 = 0;
			int temp = 0;
			for (int j = 0; j < i; j++)
			{
				temp = vec[j] * 2;
				if (temp > vec[i - 1])
				{
					min1 = temp;
					break;
				}
			}
			for (int j = 0; j < i; j++)
			{
				temp = vec[j] * 3;
				if (temp > vec[i - 1])
				{
					min2 = temp;
					break;
				}
			}
			for (int j = 0; j < i; j++)
			{
				temp = vec[j] * 5;
				if (temp > vec[i - 1])
				{
					min3 = temp;
					break;
				}
			}
			int minnum = min(min(min1, min2), min3);
			vec[i] = minnum;
		}
		return vec[index - 1];
	}
};

然后看到了大佬们的代码,虎躯一震,仅供参考:

链接:https://www.nowcoder.com/questionTerminal/6aa9e04fc3794f68acf8778237ba065b
来源:牛客网

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        if (index<=0) return 0;
        if (index==1) return 1;
        vector<int>k(index);k[0]=1;
        int t2=0,t3=0,t5=0;
        for (int i=1;i<index;i++) {
            k[i]=min(k[t2]*2,min(k[t3]*3,k[t5]*5));
            if (k[i]==k[t2]*2) t2++;
            if (k[i]==k[t3]*3) t3++;
            if (k[i]==k[t5]*5) t5++;
        }
        return k[index-1];
    }
};

猜你喜欢

转载自blog.csdn.net/Shile975/article/details/89245454