多种思路解决问题

博客主要介绍了两个算法问题的多种解法。一是多数问题,给定数组找出现次数超一半的元素,可通过排序或哈希map解决;二是幂次方问题,判断整数是否为3的幂次方,有利用库函数、特性、进制、推理公式等六种方法,部分给出代码实现。

1.多数问题

  • 问题描述:给定一个大小为n的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于(n/2)的元素;你可以假设数组是非空的,并且给定的数组总是存在多数元素。
    输入:[3,2,3],输出:3

法一:先对给定的数组进行排序,然后由于多数的个数是大于所有数据的一半,所以返回排序后下标为中数的数值,这个数值肯定是所求数值。

  1. 代码实现
int Get_Elem(vector<int>& vec)
{
	sort(vec.begin(),vec.end());
	return vec[vec.size()/2];
}

法二:利用哈希map对数组进行遍历,计算每个数值出现的次数,然后返回次数过半的数值

  1. 代码实现:
int Get_Elem(vector<int>& vec)
{
	unorder_map<int,int> counts;
	//          key,value=>ref;
	int ma = 0,cnt = 0;
	for (int x : vec)
	{
		++counts[x];
		if (counts[x] > cnt)
		{
			ma = x;
			cnt = counts[x];
		}
	}
	return ma;
}

2幂次方问题

  • 问题描述:给定一个整数,写一个函数来判断它是否是3的幂次方。
    例:输入:27,输出:true;
    输入:0,输出:false;
    输入:9,输出:true;

法一:利用库函数pow(),用循环计算pow(3,i)的值是否等于所给整数

  1. 代码实现
bool IsOqwer(int n)
{
	bool res = false;
	if (n < 1)
		return false;
	int i = 1;
	while (pow(3, i) < n)
	{
		++i;
	}
	if (pow(3, i) == n)
	{
		res = true;
	}
}

法二:利用特性,由于3的幂次方对3取模都为0,而且除3之后的商对3取模也得3,利用循环每次对n除以3,最后只要n为1,就是我们想要的值。

  1. 代码实现:
bool IsPower(int n)
{
	bool res = false;
	if (n < 1)
		return res;
	while (n % 3 == 0)
	{
		n = n / 3;
	}
	if (n == 1)
	{
		res = true;
	}
	return res;
}

法三:利用进制,先把整数转为3进制的字符串,只要判断第一位是否为1,且后面全是0,就为3的幂次方,否则不是。

3.代码实现:

bool IsPower(int n)
{
	bool res = false;
	if (n < 1)
		return res;
	char buff[256] = { '\0' };
	itoa(n, buff, 3);
	int i = 0;
	if (buff[i] == '1')
	{
		++i;
		while (buff[i] != '\0')
		{
			if (buff[i] != '0')
			{
				break;
			}
			++i;
		}
		if (buff[i] == '\0')
		{
			res = true;
		}
	}
	return res;
}

法四:推理公式,利用数学方法,换底公式

在这里插入图片描述
(此方法不太完善,有一定的精度问题)

  1. 代码实现:
bool IsPower(int n)
{
	bool res = false;
	if (n < 1)
		return res;
	return (int)((log10(n) / log10(3))) % 1 == 0;
}

法五:由于不能超过整形的最大值,可以先计算出在整形范围内的最大幂是多少,然后用最大幂次方的结果对整数取模,看是否等于0,若等于0则为3的幂次方。

5.代码实现:


bool IsPower(int n)
{
	return n > 1 && 1162261467 % n == 0;
}

法六:由于幂次方的增长很快,可得出在整形范围内3的幂次方只有19个,我们可以把这19个值一一列举出来存放到数组中,然后采取比较的方法看整数是否存在于这几个数中。

(此方法目前只提供思想)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值