题目描述:
给定一个非负整数数组 A,如果该数组每对相邻元素之和是一个完全平方数,则称这一数组为正方形数组。返回 A 的正方形排列的数目。两个排列 A1 和 A2 不同的充要条件是存在某个索引 i,使得 A1[i] != A2[i]。
示例 1:
输入:[1,17,8]
输出:2
解释:
[1,8,17] 和 [17,8,1] 都是有效的排列。
示例 2:
输入:[2,2,2]
输出:1
提示:
1 <= A.length <= 12
0 <= A[i] <= 1e9
思路:
整体思路跟47题的全排列II差不多,剪枝部分要多考虑一个相邻元素之和不为完全平方数的情况就可以了。
代码部分我写了两个,一个是创建了个动态数组来保存排列,执行时间为0ms,但需要消耗内存8MB,改了下效果也没有很好,然后就失去兴趣了,有空在回来看看吧
代码
代码1:
class Solution {
public:
vector<int> vis; //标记数组
int count = 0;
int numSquarefulPerms(vector<int>& nums) {
vector<int> perm; // 保存一个排列
sort(nums.begin(),nums.end());
vis.resize(nums.size());
backtrack(nums,perm, 0); // 记录正方形数组的个数
return count;
}
// 回溯函数 + 剪枝
void backtrack(vector<int>& nums, vector<int>perm, int index){
if(index == nums.size()){
// ans.push_back(perm);
++count;
return;
}
for(int i = 0; i < nums.size(); ++i){
// 剪枝1 相邻元素之和非完全平方数
if(!perm.empty() && floor(sqrt(perm.back() + nums[i]) + 0.5) != sqrt(nums[i] + perm.back())){
continue;
}
// 剪枝2 当前元素已用过,或者重复数字未按顺序插入
if(vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])){
continue;
}
perm.push_back(nums[i]);
vis[i] = 1;
backtrack(nums,perm, index + 1);
vis[i] = 0;
perm.pop_back();
}
}
// 判断是否为完全平方数
// bool is_Perfect_Square(vector<int>& perm){
// bool flat = true;
// for(int i = 1; i < perm.size(); ++i){
// int sum = perm[i] + perm[i - 1];
// // int sqrt_num = (int)sqrt(sum);
// if(floor(sqrt(sum) + 0.5) != sqrt(sum)){
// flat = false;
// return flat;
// }
// }
// return flat;
// }
};
代码2:
class Solution {
public:
int count = 0;
int numSquarefulPerms(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<int> vis(nums.size());
backtrack(nums,-1, 0); // 记录正方形数组的个数
return count;
}
// 回溯函数 + 剪枝
void backtrack(vector<int>& nums, int perm, int index){
if(index == nums.size()){
++count;
return;
}
for(int i = 0; i < nums.size(); ++i){
// 剪枝2 当前元素已插入,或者重复数字未按顺序插入
if(vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])){
continue;
}
// 剪枝1 相邻元素之和非完全平方数
if(perm != -1 && floor(sqrt(perm + nums[i]) + 0.5) != sqrt(nums[i] + perm)){
continue;
}
vis[i] = 1;
backtrack(nums,nums[i], index + 1);
vis[i] = 0;
}
}
};