47. Permutations II

Explanation

To solve this problem, we can use backtracking to generate all unique permutations of the given array with duplicates. We will sort the input array to handle duplicates easily. During the backtracking process, we will keep track of used elements to avoid duplicates in the permutations.

  1. Sort the input array to handle duplicates.

  2. Initialize an empty list to store the result.

  3. Implement a backtracking function that takes the current permutation, the array of used elements, and the input array as parameters.

  4. In the backtracking function:

    • If the current permutation's length is equal to the input array's length, add it to the result list.
    • Iterate through the input array:
      • If the current element is already used or equals the previous element and the previous element is not used, skip to avoid duplicates.
      • Mark the current element as used, add it to the current permutation, and recursively call the backtracking function.
      • Backtrack by marking the current element as unused and removing it from the current permutation.
  5. Return the result list.

Time Complexity: O(N * N!), where N is the length of the input array. The time complexity is influenced by the number of unique permutations generated.

Space Complexity: O(N), where N is the length of the input array. The space complexity is due to the recursion stack and the result list.

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> result = new ArrayList<>();
        backtrack(result, new ArrayList<>(), new boolean[nums.length], nums);
        return result;
    }
    
    private void backtrack(List<List<Integer>> result, List<Integer> tempList, boolean[] used, int[] nums) {
        if (tempList.size() == nums.length) {
            result.add(new ArrayList<>(tempList));
        } else {
            for (int i = 0; i < nums.length; i++) {
                if (used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i - 1])) {
                    continue;
                }
                used[i] = true;
                tempList.add(nums[i]);
                backtrack(result, tempList, used, nums);
                used[i] = false;
                tempList.remove(tempList.size() - 1);
            }
        }
    }
}

Code Editor (Testing phase)

Improve Your Solution

Use the editor below to refine the provided solution. Select a programming language and try the following:

  • Add import statement if required.
  • Optimize the code for better time or space complexity.
  • Add test cases to validate edge cases and common scenarios.
  • Handle error conditions or invalid inputs gracefully.
  • Experiment with alternative approaches to deepen your understanding.

Click "Run Code" to execute your solution and view the output. If errors occur, check the line numbers and debug accordingly. Resize the editor by dragging its bottom edge.