假设有从 1 到 N 的 N 个整数,如果从这 N 个数字中成功构造出一个数组,使得数组的第 i 位 (1 <= i <= N) 满足如下两个条件中的一个,我们就称这个数组为一个优美的排列。条件:
- 第 i 位的数字能被 i 整除
- i 能被第 i 位上的数字整除
现在给定一个整数 N,请问可以构造多少个优美的排列?
示例1:
输入: 2 输出: 2 解释: 第 1 个优美的排列是 [1, 2]: 第 1 个位置(i=1)上的数字是1,1能被 i(i=1)整除 第 2 个位置(i=2)上的数字是2,2能被 i(i=2)整除 第 2 个优美的排列是 [2, 1]: 第 1 个位置(i=1)上的数字是2,2能被 i(i=1)整除 第 2 个位置(i=2)上的数字是1,i(i=2)能被 1 整除
说明:
- N 是一个正整数,并且不会超过15。
方法1:
思路: 对全排列进行改造。 void dfs函数变为int dfs 函数。
现在 int dfs()函数的伪代码如下:
int dfs(int len){ if(len==某个数){ return 1; } int res=0; 循环过程——————{ res+= dfs(len+1,); } return res; }
同时因为是通过筛选,因此在交换过程中加入判断条件,代码如下:
JAVA
class Solution { public int countArrangement(int N) { int[] nums=new int[N]; for(int i=0;i<N;i++){ nums[i]=i+1; } return dfs(nums,0); } public void swap(int[] nums,int i,int j){ int temp=nums[i]; nums[i]=nums[j]; nums[j]=temp; } //DFS返回的是int类型。 public int dfs(int[] nums,int len){ if(len==nums.length){ return 1; //只要能够进行到回溯的终止条件,也就是出现了符合的排列,结果+1. } int res=0; for(int i=len;i<nums.length;i++){ //nums[i] num[len] 进行交换,由于Len可能是0,因此+1.这里nums[len]%(i+1)==0反而不成立! if(nums[len]%(len+1)==0||(len+1)%nums[i]==0){ swap(nums,i,len); res+=dfs(nums,len+1); swap(nums,i,len); } } return res; } }
c++:
class Solution { public: int dfs(vector<int>& nums,int len){ if(len==nums.size()){ return 1; } int res=0; for(int i=len;i<nums.size();i++){ if(nums[i]%(len+1)==0||(len+1)%nums[i]==0){ swap(nums[i],nums[len]); res+=dfs(nums,len+1); swap(nums[i],nums[len]); } } return res; } int countArrangement(int N) { vector<int> nums(N); for(int i=0;i<N;i++)nums[i]=i+1; return dfs(nums,0); } };
方法2:
class Solution { public: //思路:对每一位从1-N的数字进行判断,比如1 2 3 4 5 . //一号位可以放置:1 2 3 4 5.二号位可以放置:1 2 4 三号位只能放置:3 四号位可以放置1 2 4 //同时已经放置过的数字不能再使用了,用vis[i]==1来表示。 //判断的条件为:if(vis[i]==0&&(i%len==0||len%i==0)) int countArrangement(int N) { int count=0; vector<int> vis(N+1,0); dfs(count,N,vis,1); return count; } void dfs(int& count,int N,vector<int>& vis,int len){ if(len>N){ count++; return; } for(int i=1;i<=N;i++){ if(vis[i]==0&&(i%len==0||len%i==0)){ vis[i]=1; dfs(count,N,vis,len+1); vis[i]=0; } } } };