【Leetcode】869. 重新排序得到 2 的幂

题目描述:

从正整数 N 开始,我们按任何顺序(包括原始顺序)将数字重新排序,注意其前导数字不能为零。

如果我们可以通过上述方式得到 2 的幂,返回 true;否则,返回 false

示例 1:

输入:1
输出:true

示例 2:

输入:10
输出:false

示例 3:

输入:16
输出:true

示例 4:

输入:24
输出:false

示例 5:

输入:46
输出:true

提示:

  1. 1 <= N <= 10^9

解题思路:

本题理解的题意就是:给出一串数字,他的 第一个数字不为0的所有全排列中如果有2的幂返回true。

AC代码:

class Solution {
public:
   bool reorderedPowerOf2(int n) {
	int tmp;
	vector<int> a;
	while (n>0)
	{
		a.push_back(n % 10);
		n /= 10;
	}
	sort(a.begin(), a.end());
	do
	{
		if (a[0] == 0) continue;
		tmp = 0;
		for (int i = 0; i<a.size(); i++)
			tmp = tmp * 10 + a[i];
		for (int i = 0; i<30; i++)
			if (tmp == (1 << i)) return true;
	} while (next_permutation(a.begin(), a.end()));
	return false;
  }
};
    

个人尝试(内存超限):

其实下面这个才是我的原始代码,不过过不了,内存超限,感觉应该是全排列递归过程导致的,但是我不知道怎么解决。如果有大家有解决的办法,还希望能指教一下,先谢过了。

bool Powerof2(int n)
{
	while (n>1)
	{
		if (n % 2 == 1)return false;
		n = n / 2;
	}
	return true;
}
void Arrangement(vector<vector<int>>& res, vector<int> nums, int begin)
{
	if (begin == nums.size())
	{
		res.push_back(nums);
		return;
	}
	for (int i = begin; i < nums.size(); ++i)
	{
		if (i == begin || nums[i] != nums[begin])
		{
			swap(nums[i], nums[begin]);
			Arrangement(res, nums, begin + 1);
			swap(nums[i], nums[begin]);
		}
	}
}
bool reorderedPowerOf2(int N) 
{
	vector<int> nums;
	while (N)
	{
		nums.push_back(N % 10);
		N = N / 10;
	}
	vector<vector<int>> res;
	Arrangement(res, nums, 0);
	for (int i = 0; i < res.size(); i++)
	{
		if (res[i][0] == 0)continue;
		int n = 0;
		for (int j = 0; j < res[0].size(); j++)
		{
			n = n * 10 + res[i][j];
		}
		if(Powerof2(n)==true) return true;
	}
	return false;
}

逆向思维:

网上找了一会,还是没有解决全排列向量内存超限的问题,又看了一下其他牛人的AC代码,发现了一个新的思路。很佩服这些牛人的思维,感觉自己想法太僵化了。有待提升啊(^_^)。

牛人的解题思路:逆向思维,先枚举给定范围内所有的2的幂,然后将这些数字排序,然后和输入的数字排序后比较,相同即是。

bool reorderedPowerOf2(int N) {
	if (N == 1) return true;

	set<string> two;
	for (int i = 0; i<40; i++) {
		string s = to_string(1LL << i);
		sort(s.begin(), s.end());
		two.insert(s);
	}

	string s = to_string(N);
	sort(s.begin(), s.end());
	return two.find(s) != two.end();

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值