题目描述:
给定一个非负整数数组 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-squareful-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
每次添加一个元素,逐步添加;
递归结束条件:rest==0,元素添加完成
子问题:每添加一个元素,在剩下的元素中再找一个元素添加进去。
去重:不用使用map一样可以去重,经过排序,然后下一个相同的元素在相同位置舍弃。
样例:5 11 5 4 5
sort:4 5 5 5 11
选择第一个4 ,第二个5
与
选择第一个4,第三个5
两者等价(剩余元素相同)因此可以直接舍弃这种情况。
可以尝试不使用map(map目的就是去重,前边情况已经可以解决重复)
作者:allforyou
链接:https://leetcode-cn.com/problems/number-of-squareful-arrays/solution/chao-100zhu-shi-xiang-xi-cmapshen-du-you-0jw3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
代码:
class Solution {
public:
//判断是不是完全平方数
bool isSquare(const int m){
int a=sqrt(m);
return a*a==m?true:false;
}
void getPermutation(vector<int> &nums,vector<int> &subres,map<vector<int>,int> &myres,int rest){
//数组中将元素添加完整之后返回
if(rest==0)
{
myres[subres]+=1;
return ;
}
int pre=-1;
//for循环结束为找到相应的元素(代码执行完毕自动返回),不用处理。
for(int i=0;i<nums.size();i++){
//已遍历元素置为-1(题目中为非零)
if(nums[i]==-1)
continue;
//由于是已经排好序,因此后一个元素如果等于前一个元素,直接舍弃
if(!subres.empty()&&isSquare(nums[i]+subres.back())&&nums[i]!=pre){
//标记已经用过
subres.push_back(nums[i]);
nums[i]=-1;
//选取下一个元素
getPermutation(nums,subres,myres,rest-1);
//标记恢复
nums[i]=subres.back();
subres.pop_back();
pre=nums[i];
}
//添加第一个元素时
if(subres.empty())
{
subres.push_back(nums[i]);
nums[i]=-1;
getPermutation(nums,subres,myres,rest-1);
nums[i]=subres.back();
subres.pop_back();
}
}
}
int numSquarefulPerms(vector<int>& nums) {
map<vector<int>,int> myres;
vector<int> subres;
//先排序,与去重代码相契合,能够很快找到相同元素并且舍弃
sort(nums.begin(),nums.end());
getPermutation(nums,subres,myres,nums.size());
return myres.size();
}
};
作者:allforyou
链接:https://leetcode-cn.com/problems/number-of-squareful-arrays/solution/chao-100zhu-shi-xiang-xi-cmapshen-du-you-0jw3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
优化版:
class Solution {
int count=0;
public:
bool isSquare(const int m){
int a=sqrt(m);
return a*a==m?true:false;
}
void getPermutation(vector<int> &nums,vector<int> &subres,int rest){
if(rest==0)
{
count++;
return ;
}
int pre=-1;
for(int i=0;i<nums.size();i++){
if(nums[i]==-1)
continue;
if(!subres.empty()&&isSquare(nums[i]+subres.back())&&nums[i]!=pre){
subres.push_back(nums[i]);
nums[i]=-1;
getPermutation(nums,subres,rest-1);
nums[i]=subres.back();
subres.pop_back();
pre=nums[i];
}
if(subres.empty()&&pre!=nums[i])
{
pre=nums[i];
subres.push_back(nums[i]);
nums[i]=-1;
getPermutation(nums,subres,rest-1);
nums[i]=subres.back();
subres.pop_back();
}
}
}
int numSquarefulPerms(vector<int>& nums) {
vector<int> subres;
sort(nums.begin(),nums.end());
getPermutation(nums,subres,nums.size());
return count;
}
};