题意:

image.png

解题思路:

  1. 思路:回溯
  2. 1. 从前往后枚举每一位,每一次选择一个没有使用过的数字,然后将该数字置为已使用;
  3. 2. 然后将该数字加入数组中,递归下一层;
  4. 3. 递归终止返回时,将该数字改为“未被使用状态”,并从数组中移除该数字;
  5. 注意:if ($i > 0 && $nums[$i] == $nums[$i - 1] &&
  6. $this->visited[$i - 1] == 0) continue;
  7. -》剪枝,该元素与前一个元素相等,且前一个元素访问过,不使用,直接跳过

PHP代码实现:

  1. class Solution {
  2. public $res = [];
  3. public $visited = [];
  4. function permuteUnique($nums) {
  5. sort($nums);
  6. $this->dfs([], $nums);
  7. return $this->res;
  8. }
  9. function dfs($array, $nums) {
  10. if (count($array) == count($nums)) {
  11. array_push($this->res, $array);
  12. return;
  13. }
  14. for ($i = 0; $i < count($nums); $i++) {
  15. // 第一次剪枝,去掉已经访问过的
  16. if (isset($this->visited[$i]) && $this->visited[$i] == 1) continue;
  17. // 第二次剪枝,该元素与前一个元素相等,且前一个元素访问过
  18. if ($i > 0 && $nums[$i] == $nums[$i - 1] && $this->visited[$i - 1] == 0) continue;
  19. $this->visited[$i] = 1;
  20. array_push($array, $nums[$i]);
  21. $this->dfs($array, $nums);
  22. array_pop($array);
  23. $this->visited[$i] = 0;
  24. }
  25. }
  26. }

GO代码实现:

  1. func permuteUnique(nums []int) [][]int {
  2. var pathNum []int
  3. var used = make([]bool, len(nums))
  4. var result [][]int
  5. sort.Ints(nums)
  6. dfs(nums, pathNum, used, &result)
  7. return result
  8. }
  9. func dfs(nums, pathNums []int, used []bool, result *[][]int) {
  10. if len(nums) == len(pathNums) {
  11. tmp := make([]int, len(nums))
  12. // 切片底层公用数据,所以要copy
  13. copy(tmp, pathNums)
  14. *result = append(*result, tmp)
  15. return
  16. }
  17. // 开始遍历原始数组的每个数字
  18. for i := 0; i < len(nums); i++ {
  19. if used[i] { continue }
  20. // 上一个元素与当前元素相同并且没有访问过
  21. if i != 0 && nums[i] == nums[i - 1] && !used[i - 1] {
  22. continue
  23. }
  24. used[i] = true
  25. pathNums = append(pathNums, nums[i])
  26. dfs(nums, pathNums, used, result)
  27. pathNums = pathNums[:len(pathNums)-1]
  28. used[i] = false
  29. }
  30. }