剑指offer 34---丑数

题目:

求按从小到大的第1500个丑数。

丑数:

只包含因子2,3,5的数称为丑数。所谓一个数m是另一个数n的因子,是指n能被m整除。

例:

   

解1:直观解法,从1开始计算,然后计数,直到第1500个丑数

缺陷:每个整数都需要计算,效率非常低

//判断是不是丑数
bool IsUflyNum(int num)
{
	if (num <= 0)
	{
		return false;
	}
	while (num % 2 == 0)    
	{
		num = num / 2;
	}
	while (num % 3 == 0)
	{
		num = num / 3;
	}
	while (num % 5 == 0)
	{
		num = num / 5;
	}
	//要求不能有除了2,3,5之外的因子
	return (num == 1) ? true: false;
}

int GetNum(int n)    //此处n代表第n个丑数
{
	if (n <= 0)
	{
		return 0;
	}
	int count = 0;
	int i = 1;
	while (1)
	{
		if (count <= n)
		{
			if (IsUflyNum(i) == 1)    //说明此时的i为丑数
			{
				count++;
			}
		}
		if (count == n)
		{
			return i;
		}
		++i;
	}
}

void TestUglyNum()
{
	int tty = GetNum(1500);
	cout << tty << endl;
}

解2: 用空间换时间

缺陷:需要额外开辟空间来存储丑数


int Min(int num2, int num3, int num5)    //返回三个数中的最小的
{
	int temp = (num2 < num3) ? num2 : num3;    //先找出num2,num3中的最小值
	return (temp < num5) ? temp : num5;
}

int GetUglyNum(int n)      //此处n代表为第n个丑数
{
	if (n <= 0)
	{
		return 0;
	}
	int* temp = new int[n];    //开辟一个大小为n的数组存放排序的丑数
	assert(temp);   //判断数组空间是否开辟成功
	for (int i = 0; i < n; ++i)
	{
		temp[i] = 0;
	}
	int* ptr2 = temp;
	int* ptr3 = temp;
	int* ptr5 = temp;
	temp[0] = 1;   //第一个丑数为1,不用计算
	int index = 1;    //当前数组下标
	while (index < n)
	{
		//比较三个指针指向位置的值分别乘以2,3,5,取最小值存储
		int min = Min((*ptr2) * 2, (*ptr3) * 3, (*ptr5) * 5);     //此时找到三个数里面的最小值
		temp[index] = min;
		index++;
		while (min >= (*ptr2) * 2)
		{
			++ptr2;
		}
		while (min >= (*ptr3) * 3)
		{
			++ptr3;
		}
		while (min >= (*ptr5) * 5)
		{
			++ptr5;
		}
	}
	int tty = temp[n - 1];
	delete[] temp;
	return tty;
}

void TestUglyNum()
{
	int tty = GetUglyNum(1500);
	cout << tty << endl;
}


  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值