↓Skip to main content
  1. LeetCode/

LeetCode 47: Permutations II

·2 mins· ·
LeetCode Medium Array Backtracking Sorting
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-10-22

  • Submissions: Wrong Answer → Accepted

Approach
#

Permutations with duplicates need deduplication (Backtracking Variation 4). After sorting, if nums[i] == nums[i - 1] and nums[i - 1] is currently unused, this level already tried that value, so skip. Equal numbers then appear only in their original order, and each permutation is generated once.

My Attempts
#

Attempt 1 had the right skip condition but forgot to sort, so equal numbers were not adjacent and the skip never fired: [0, 1, 0] returned duplicate permutations. Adding nums.sort() passed.

Solution
#

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res, path = [], []
        used = [False] * len(nums)
        def dfs():
            if len(path) == len(nums):
                res.append(path[:])
                return
            for i in range(len(nums)):
                if used[i] or (i > 0 and nums[i] == nums[i - 1] and not used[i - 1]):
                    continue
                used[i] = True
                path.append(nums[i])
                dfs()
                path.pop()
                used[i] = False
        dfs()
        return res

Complexity
#

Time O(n · n!), space O(n) excluding output.

Mistakes to Avoid
#

  • Sort before deduplicating so equal values are adjacent.

Interview Explanation
#

With duplicates I sort and, while backtracking, skip a number equal to the previous one when the previous is unused, since that value was already tried at this level. Time O(n · n!).

Related

LeetCode 49: Group Anagrams
·2 mins
LeetCode Medium Array Hash-Table String Sorting
LeetCode 49 note: use each string’s sorted form as a key; strings sharing a key form one anagram group
LeetCode 56: Merge Intervals
·2 mins
LeetCode Medium Array Sorting Quicksort
LeetCode 56 note: sort by start; if a new interval starts at or before the last merged end, merge (taking the max end), otherwise open a new one
LeetCode 39: Combination Sum
·2 mins
LeetCode Medium Array Backtracking
LeetCode 39 note: numbers may be reused, so the next level starts at i (not i + 1), which also avoids duplicates differing only in order
LeetCode 40: Combination Sum II
·2 mins
LeetCode Medium Array Backtracking
LeetCode 40 note: each number is used once and duplicates exist, so sort, start the next level at i + 1, and skip equal values within a level
LeetCode 46: Permutations
·2 mins
LeetCode Medium Array Backtracking
LeetCode 46 note: each level picks one unused number, marked in a used array, and records when the path is full
LeetCode 15: 3Sum
·2 mins
LeetCode Medium Array Two-Pointers Sorting
LeetCode 15 note: sort, fix the first number, and find the other two with converging pointers, skipping equal values at all three positions to avoid duplicate triplets