螺竹编程
发布于 2024-05-26 / 7 阅读
0

算法题/排列组合:含重复数字的排列

题目

给定一个可包含重复数字的序列nums,按任意顺序返回所有不重复的全排列。

示例1:

输入:nums=[1,1,2]
输出:[[1,1,2],[1,2,1],[2,1,1]]
解释:

示例2:

输入:nums=[1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
解释:

解答

Java

public List<List<Integer>> permuteUnique(int[] nums) {
    List<List<Integer>> permutes = new ArrayList<>();
    List<Integer> permuteList = new ArrayList<>();
    Arrays.sort(nums);  // 排序
    boolean[] hasVisited = new boolean[nums.length];
    backtracking(permuteList, permutes, hasVisited, nums);
    return permutes;
}


private void backtracking(List<Integer> permuteList, List<List<Integer>> permutes, boolean[] visited, final int[] nums) {
    if (permuteList.size() == nums.length) {
        permutes.add(new ArrayList<>(permuteList));
        return;
    }


    for (int i = 0; i < visited.length; i++) {
        if (i != 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
            continue;  // 防止重复
        }
        if (visited[i]){
            continue;
        }
        visited[i] = true;
        permuteList.add(nums[i]);
        backtracking(permuteList, permutes, visited, nums);
        permuteList.remove(permuteList.size() - 1);
        visited[i] = false;
    }
}

JavaScript

function permuteUnique(nums) {
  let permutes = [];
  let permuteList = [];
  nums.sort((a, b) => a - b); // 排序
  let hasVisited = new Array(nums.length).fill(false);
  backtracking(permuteList, permutes, hasVisited, nums);
  return permutes;
}

function backtracking(permuteList, permutes, visited, nums) {
  if (permuteList.length === nums.length) {
    permutes.push([...permuteList]);
    return;
  }

  for (let i = 0; i < visited.length; i++) {
    if (i !== 0 && nums[i] === nums[i - 1] && !visited[i - 1]) {
      continue; // 防止重复
    }
    if (visited[i]) {
      continue;
    }
    visited[i] = true;
    permuteList.push(nums[i]);
    backtracking(permuteList, permutes, visited, nums);
    permuteList.pop();
    visited[i] = false;
  }
}

Python

def permute_unique(nums):
    permutes = []
    permute_list = []
    nums.sort()  # 排序
    visited = [False] * len(nums)
    backtracking(permute_list, permutes, visited, nums)
    return permutes

def backtracking(permute_list, permutes, visited, nums):
    if len(permute_list) == len(nums):
        permutes.append(list(permute_list))
        return

    for i in range(len(visited)):
        if i != 0 and nums[i] == nums[i - 1] and not visited[i - 1]:
            continue  # 防止重复
        if visited[i]:
            continue
        visited[i] = True
        permute_list.append(nums[i])
        backtracking(permute_list, permutes, visited, nums)
        permute_list.pop()
        visited[i] = False

Go

func permuteUnique(nums []int) [][]int {
	permutes := [][]int{}
	permuteList := []int{}
	sort.Ints(nums) // 排序
	visited := make([]bool, len(nums))
	backtracking(&permuteList, &permutes, visited, nums)
	return permutes
}

func backtracking(permuteList *[]int, permutes *[][]int, visited []bool, nums []int) {
	if len(*permuteList) == len(nums) {
		temp := make([]int, len(*permuteList))
		copy(temp, *permuteList)
		*permutes = append(*permutes, temp)
		return
	}

	for i := 0; i < len(visited); i++ {
		if i != 0 && nums[i] == nums[i-1] && !visited[i-1] {
			continue // 防止重复
		}
		if visited[i] {
			continue
		}
		visited[i] = true
		*permuteList = append(*permuteList, nums[i])
		backtracking(permuteList, permutes, visited, nums)
		*permuteList = (*permuteList)[:len(*permuteList)-1]
		visited[i] = false
	}
}