算法---丑数I II

题目

丑数: 一个数分解质因数后只包括2、3、 5,就说明这是一个丑数。1 是 丑数
丑数就是只包含质因数 2, 3, 5 的正整数。

问题1:
判断一个数是否是丑数
思路
根据手动(就是在纸上手算)分解质因数的思路, 首先尝试2,直至不能再被 2 整除,然后试 3 , 然后 5.  最后如果商为 1  说明是丑数
如果不是 1 那么就说明不是丑数。
代码
#include<iostream>
#include<vector>

using namespace std;

// 判断一个数是不是丑数: 按照手动的分解质因数的方法,从 2 试起,知道不能再分,然后 3 .. 5 
class Solution {
public:
	bool isUgly(int num) 
	{
		if (num == 0)
			return false;
		if (num == 1)
			return true;
		int n = num;
		if ((num % 2 == 0) || (num % 3 == 0) || (num % 5 == 0))
		{
			while(n % 2 == 0 && n != 0)
			{
				n = n / 2;
			}
			while (n % 3 == 0 && n != 0)
			{
				n = n / 3;
			}
			while (n % 5 == 0 && n != 0)
			{
				n = n / 5;
			}
			if (n == 1)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
};
问题2

计算第 n 个丑数

思路

通过遍历每个数,判断是否是丑数会超时。
丑数都是 2 3 5 乘积得到的,所以可以采用生成丑数的方式, 问题要求第 n 个,所以生成的丑数需要保证有序,并且不能漏掉任何一个丑数。
三指针法: 使用三个标志位,分别标记已经计算出的丑数乘以2、3、5刚好大于已经计算出的最后一个丑数(即当前最大值)的数组索引。
然后取三个乘积中的最小值,就是下一个丑数,并保存。更新三个标志。直至得到的丑数数量为 n 返回第 n 个值

代码
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;
// 计算第 n 个丑数
class Solution {
public:
	// 思路:通过生成丑数的方法,三种生成方式最小的就是下一个丑数
	// 生成方式:已经得到的丑数分别乘以 2 3 5
	// 2 3 5 三种方式的因数通过数组下标记录,每生成一个丑数,更新三种方式的下标,更新为乘积刚好大于最新的丑数的值
	int min(int a, int b, int c)
	{
		int x = a < b ? a : b;
		return x < c ? x : c;
	}
	int nthUglyNumber(int n) 
	{
		if (n == 0)
			return 0;
	
		int cur = 1; // 当前最大丑数
		int number = 0; // 已经计算出的丑数数量

		int index_2 = 0;
		int index_3 = 0;
		int index_5 = 0;
		vector<int> numbers(n, 0);
		numbers[0] = 1;

		while (number < n-1)
		{
			cur = min(numbers[index_2] * 2, numbers[index_3] * 3, numbers[index_5] * 5);
			number++;
			numbers[number] = cur;

			// 寻找与 2 3 5 相乘的起始值
			while (numbers[index_2] * 2 <= cur)
			{
				index_2++;
			}
			while (numbers[index_3] * 3 <= cur)
			{
				index_3++;
			}
			while (numbers[index_5] * 5 <= cur)
			{
				index_5++;
			}
			
		}
		return numbers[number];
		
	}
};
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值