一、leetcode 526 优美的排列
题目描述:
假设有从 1 到 N 的 N 个整数,如果从这 N 个数字中成功构造出一个数组,使得数组的第 i 位 (1 <= i <= N) 满足如下两个条件中的一个,我们就称这个数组为一个优美的排列。条件:
第 i 位的数字能被 i 整除
i 能被第 i 位上的数字整除
现在给定一个整数 N,请问可以构造多少个优美的排列?
思路:
回溯法
代码如下:
class Solution {
int res=0;
public:
int countArrangement(int n) {
vector<bool>visited(n+1,false);
dfs(1,n,visited);
return res;
}
void dfs(int cur,int n,vector<bool>& visited){
if(cur==1+n){
res++;
return;
}
for(int i=1;i<=n;i++){
if(!visited[i]&&(i%cur==0||cur%i==0)){
visited[i]=true;
dfs(cur+1,n,visited);
visited[i]=false;
}
}
}
};
二、leetcode 667 优美的排列II
题目描述:
给定两个整数 n 和 k,你需要实现一个数组,这个数组包含从 1 到 n 的 n 个不同整数,同时满足以下条件:
① 如果这个数组是 [a1, a2, a3, … , an] ,那么数组 [|a1 - a2|, |a2 - a3|, |a3 - a4|, … , |an-1 - an|] 中应该有且仅有 k 个不同整数;.
② 如果存在多种答案,你只需实现并返回其中任意一种.
思路:
找规律
k=1 : 1,2,3,4,5,6,7,8
k=2 : 1,8,7,6,5,4,3,2(第一个位置的数保留,后面的翻转)
k=3 : 1,8,2,3,4,5,6,7(前两个位置的数保留,后面的翻转)
k=4 : 1,8,2,7,6,5,4,3(前三个位置的数保留,后面的翻转)
代码如下:
class Solution {
public:
vector<int> constructArray(int n, int k) {
vector<int>res;
for(int i=1;i<=n;i++){
res.push_back(i);
}
int cnt=1;
while(cnt<k){
reverse(res.begin()+cnt,res.end());
cnt++;
}
return res;
}
};