给定一个数字n,求[1, n]这n个数字的排列组合有多少个
条件:相邻的两个数之间的绝对值大于1
按字典序输出
示例
输入
4
输出
2 4 1 3
3 1 4 2
解题思路
采用DFS或者回溯
代码
Java
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
boolean[] visited = new boolean[n + 1];
helper(n, visited, 0, new ArrayList<>());
}
public static void helper(int n, boolean[] visited, int count, List<Integer> res) {
if (count == n) {
for (int i = 0; i < n; i++) {
System.out.print(res.get(i));
if (i < n - 1) System.out.print(" ");
else System.out.println();
}
} else {
for (int i = 1; i <= n; i++) {
if (!visited[i]) {
if (res.isEmpty() || Math.abs(res.get(res.size() - 1) - i) > 1) {
visited[i] = true;
res.add(i);
helper(n, visited, count + 1, res);
res.remove(res.size() - 1);
visited[i] = false;
}
}
}
}
}
}
输出
4
2 4 1 3
3 1 4 2
5
1 3 5 2 4
1 4 2 5 3
2 4 1 3 5
2 4 1 5 3
2 5 3 1 4
3 1 4 2 5
3 1 5 2 4
3 5 1 4 2
3 5 2 4 1
4 1 3 5 2
4 2 5 1 3
4 2 5 3 1
5 2 4 1 3
5 3 1 4 2
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void helper(int n, vector<bool>& visited, int count, vector<int> res) {
if (count == n) {
for (int i = 0; i < n; i++) {
cout << res[i];
if (i < n - 1) cout << " ";
else cout << endl;
}
}
else {
for (int i = 1; i <= n; i++) {
if (!visited[i]) {
if (res.empty() || abs(res[res.size() - 1] - i) > 1) {
res.push_back(i);
visited[i] = true;
helper(n, visited, count + 1, res);
res.pop_back();
visited[i] = false;
}
}
}
}
}
int main() {
int n;
cin >> n;
vector<bool> visted(n + 1, false);
vector<int> res;
helper(n, visted, 0, res);
return 0;
}
输出
4
2 4 1 3
3 1 4 2
5
1 3 5 2 4
1 4 2 5 3
2 4 1 3 5
2 4 1 5 3
2 5 3 1 4
3 1 4 2 5
3 1 5 2 4
3 5 1 4 2
3 5 2 4 1
4 1 3 5 2
4 2 5 1 3
4 2 5 3 1
5 2 4 1 3
5 3 1 4 2