LeetCode 47. 全排列 II

题目描述

47. 全排列 II

image-20250419031039080

思路分析

回溯算法

参考代码

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
30
31
32
func permuteUnique(nums []int) [][]int {
	var res [][]int
	var path []int
	sort.Ints(nums)
	used := make([]bool, len(nums))

	var backtrack func()
	backtrack = func() {
		if len(path) == len(nums) {
			res = append(res, append([]int{}, path...))
			return
		}
		for i := 0; i < len(nums); i++ {
			if used[i] {
				continue
			}
			if i > 0 && nums[i] == nums[i-1] && !used[i-1] {
				continue
			}

			path = append(path, nums[i])
			used[i] = true

			backtrack()

			path = path[:len(path)-1]
			used[i] = false
		}
	}
	backtrack()
	return res
}
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
func permuteUnique(nums []int) [][]int {
	var res [][]int
	var path []int                  // 存放当前排列路径
	used := make([]bool, len(nums)) // 标记每个数字是否被使用过

	// 排序,保证重复的数字相邻
	sort.Ints(nums)

	var dfs func()
	dfs = func() {
		// 如果当前路径长度等于 nums 长度,说明找到了一个完整排列
		if len(path) == len(nums) {
			res = append(res, append([]int{}, path...))
			return
		}

		// 遍历每一个数字
		for i := 0; i < len(nums); i++ {
			// 如果当前数字已被使用,跳过
			if used[i] {
				continue
			}
			// 如果当前数字和前一个数字相同,且前一个数字未被使用,跳过(去重)
			if i > 0 && nums[i] == nums[i-1] && !used[i-1] {
				continue
			}

			// 做选择
			path = append(path, nums[i])
			used[i] = true

			// 进入下一层递归
			dfs()

			// 回溯,撤销选择
			path = path[:len(path)-1]
			used[i] = false
		}
	}

	dfs()
	return res
}

➡️ 点击查看 Java 题解

1
write your code here
本文作者:
本文链接: https://hgnulb.github.io/blog/2025/25893218
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!