跳转至

3437. 全排列 III 🔒

题目描述

给定一个整数 n,一个 交替排列 是没有 两个 相邻元素 同时 为奇数或偶数的前 n 个正整数的排列。

返回所有这样的 交替排列 以字典序排序。

 

示例 1:

输入:n = 4

输出:[[1,2,3,4],[1,4,3,2],[2,1,4,3],[2,3,4,1],[3,2,1,4],[3,4,1,2],[4,1,2,3],[4,3,2,1]]

示例 2:

输入:n = 2

输出:[[1,2],[2,1]]

示例 3:

输入:n = 3

输出:[[1,2,3],[3,2,1]]

 

提示:

  • 1 <= n <= 10

解法

方法一:回溯

我们设计一个函数 \(\textit{dfs}(i)\),表示当前要填第 \(i\) 个位置的数,位置编号从 \(0\) 开始。

\(\textit{dfs}(i)\) 中,如果 \(i \geq n\),说明所有位置都已经填完,将当前排列加入答案数组中。

否则,我们枚举当前位置可以填的数 \(j\),如果 \(j\) 没有被使用过,并且 \(j\) 和当前排列的最后一个数不同奇偶性,我们就可以将 \(j\) 放在当前位置,继续递归填下一个位置。

时间复杂度 \(O(n \times n!)\),空间复杂度 \(O(n)\)。其中 \(n\) 为排列的长度。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Solution:
    def permute(self, n: int) -> List[List[int]]:
        def dfs(i: int) -> None:
            if i >= n:
                ans.append(t[:])
                return
            for j in range(1, n + 1):
                if not vis[j] and (i == 0 or t[-1] % 2 != j % 2):
                    t.append(j)
                    vis[j] = True
                    dfs(i + 1)
                    vis[j] = False
                    t.pop()

        ans = []
        t = []
        vis = [False] * (n + 1)
        dfs(0)
        return ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
    private List<int[]> ans = new ArrayList<>();
    private boolean[] vis;
    private int[] t;
    private int n;

    public int[][] permute(int n) {
        this.n = n;
        t = new int[n];
        vis = new boolean[n + 1];
        dfs(0);
        return ans.toArray(new int[0][]);
    }

    private void dfs(int i) {
        if (i >= n) {
            ans.add(t.clone());
            return;
        }
        for (int j = 1; j <= n; ++j) {
            if (!vis[j] && (i == 0 || t[i - 1] % 2 != j % 2)) {
                vis[j] = true;
                t[i] = j;
                dfs(i + 1);
                vis[j] = false;
            }
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public:
    vector<vector<int>> permute(int n) {
        vector<vector<int>> ans;
        vector<bool> vis(n);
        vector<int> t;
        auto dfs = [&](this auto&& dfs, int i) -> void {
            if (i >= n) {
                ans.push_back(t);
                return;
            }
            for (int j = 1; j <= n; ++j) {
                if (!vis[j] && (i == 0 || t[i - 1] % 2 != j % 2)) {
                    vis[j] = true;
                    t.push_back(j);
                    dfs(i + 1);
                    t.pop_back();
                    vis[j] = false;
                }
            }
        };
        dfs(0);
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
func permute(n int) (ans [][]int) {
    vis := make([]bool, n+1)
    t := make([]int, n)
    var dfs func(i int)
    dfs = func(i int) {
        if i >= n {
            ans = append(ans, slices.Clone(t))
            return
        }
        for j := 1; j <= n; j++ {
            if !vis[j] && (i == 0 || t[i-1]%2 != j%2) {
                vis[j] = true
                t[i] = j
                dfs(i + 1)
                vis[j] = false
            }
        }
    }
    dfs(0)
    return
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
function permute(n: number): number[][] {
    const ans: number[][] = [];
    const vis: boolean[] = Array(n).fill(false);
    const t: number[] = Array(n).fill(0);
    const dfs = (i: number) => {
        if (i >= n) {
            ans.push([...t]);
            return;
        }
        for (let j = 1; j <= n; ++j) {
            if (!vis[j] && (i === 0 || t[i - 1] % 2 !== j % 2)) {
                vis[j] = true;
                t[i] = j;
                dfs(i + 1);
                vis[j] = false;
            }
        }
    };
    dfs(0);
    return ans;
}

评论