全排列

一个不含重复元素的数组,列出该数组的全排列。回溯,交换,dfs(nums,i){if(i==nums.size())res.push_back(nums);for(int j=i; j<nums.size(); j++){swap(nums[i], nums[j]);dfs(nums, i+1);swap(nums[i], nums[j]);}}

返回一个可包含重复元素数组当前排列状态的下一个更大字典序的排列。交换,交换规则是重点。首先,更大字典序与本排列相异的开头在逆向遍历降序的地方,我们需要找出从逆向遍历降序的地方到排列末尾的下一个更大字典序的排列,找到逆向遍历降序的地方nums[i]>nums[i-1]后,在nums[i:]中找到j使得nums[j]>nums[i-1]>=nums[j+1],swap(nums[j], nums[i-1]),于是nums[i:]仍是非严格递减子数组,逆转nums[i:]即得结果

一个可包含重复元素的数组,列出该数组的全排列。回溯,声明vis数组,表示元素是否已被加入排列的生成中,dfs(nums){if(tmp.size()==nums.size()){res.emplace_back(tmp);return;}for(int i=0; i<nums.size(); i++)continue;vis[i]=1;tmp.emplace_back(nums[i]);dfs(nums);vis[i]=0;tmp.pop_back();}。nums回溯前记得排序,使得相同元素在一起

统计上个问题结果中相邻元素之和均为完全平方数的排列数量。在上个问题的代码continue处增加isSquareNum(tmp.back()+nums[i])条件来剪枝,当前两个数不是完全平方数,不往下找全排列。
建立满足相邻之和为完全平方数的图,不同的遍历图中节点路径个数。深度优先遍历,统计图中某元素值的个数,统计元素接下来允许遍历的相邻节点值,dfs(int x, int n){cnt[x]--;int ans=1;if(n!=0){ans=0;for(int y:neighbors[x])if(cnt[y])ans+=dfs(y,n-1);}cnt[x]--;return ans;}

参考链接:46. 全排列
31. 下一个排列
47. 全排列 II
996. 正方形数组的数目

创建于2022.3.28/10.48,修改于2022.3.30/11.05

#backtracking #dfs