Leetcode Permutations II problem solution

In the Leetcode Permutations II problem solution Given a collection of numbers, nums, that might contain duplicates, return all possible unique permutations in any order.

Example 1:

Input: nums = [1,1,2]
Output:
[[1,1,2],
[1,2,1],
[2,1,1]]


Example 2:

Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

Constraints:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

Solution in C Programming

int factorial(int n){
    return (n==0) || (n==1) ? 1 : n* factorial(n-1);
}


/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** permuteUnique(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    int tmp[21] = {0};
    int* c = calloc(numsSize, sizeof(int));
    // calculate the returnSize
    for (int i = 0; i < numsSize; i++) {
        tmp[nums[i] + 10]++;
    }
    *returnSize = 1;
    // calculate how many non-unique numbers there are (used to calculate returnSize)
    for (int i = 0; i < 20; i++) {
        if (tmp[i] > 1) {
            *returnSize*= factorial(tmp[i]);
        }
    }
    *returnSize = factorial(numsSize)/ (*returnSize == 0 ? 1 : *returnSize);
    // initialize return and columnSizes arrays
    int** ret = (int**)malloc(sizeof(int *) * (*returnSize));
    *returnColumnSizes = (int*)malloc(sizeof(int)*(*returnSize));
    for (int i = 0; i < *returnSize; i++) {
        ret[i] = calloc(numsSize, sizeof(int));
        (*returnColumnSizes)[i] = numsSize;
    }
    // generate permutations based on a non-recursive variation of the Heap's algorithm.
    // decrease and conquer method by generating all permutations that end with the last element,
    // and then switching the first and last.
    int i = 0;
    int j;
    int added = 0;
    int dupe = 0;
    // add initial permutation to the list
    memcpy(ret[added++], nums, sizeof(int) * numsSize);
    while (i < numsSize) {
        if (c[i] < i) {
            // swap elements nums(0,i) (first and last)
            if (i % 2 == 0) {
                j = nums[0];
                nums[0] = nums[i];
                nums[i] = j;
            } else {
                // swap elements nums(c[i], i)
                j = nums[c[i]];
                nums[c[i]] = nums[i];
                nums[i] = j;
            }
            // add to return array if not a duplicate
            dupe = 0;
            for (int k = 0; k < added; k++) {
                if (memcmp(nums, ret[k], sizeof(int) * numsSize) == 0) {
                    dupe = 1;
                    break;
                }
            }
            if (dupe == 0) {
                memcpy(ret[added++], nums, sizeof(int) * numsSize);
            }

            c[i] = c[i] + 1;
            i = 0;
        } else {
            c[i] = 0;
            i++;
        }
    }
    return ret;
}

Solution in C++ Programming

class Solution {
private:
    vector<vector<int>> result;
public:
    // Returns true if nums[curr] does not match with any of the characters after nums[start] 
    bool shouldSwap(vector<int> &nums, int start, int curr) { 
        for (int i = start; i < curr; i++)  
            if (nums[i] == nums[curr]) 
                return 0; 
        return 1; 
    } 
    
    void helper(vector<int>& nums, int left) {
        if (left == nums.size()) result.push_back(nums);
        else {
            for (int i = left; i < nums.size(); i++) {   // hold each character stationary.
                // Proceed further for nums[i] only if it doesn't match with any of the numbers after nums[left] 
                bool check = shouldSwap(nums, left, i);
                if (check) {
                    swap(nums[i], nums[left]);  // recurse
                    helper(nums, left + 1);
                    swap(nums[i], nums[left]);  // recurse
                }
            }
        }
    }
    
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        helper(nums, 0);   // call helper function to compute permutations.
        return result;
    }
};

Solution in Java Programming

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    public List<List<Integer>> permuteUnique(int[] nums) {
        return backTrack(nums, 0);
    }
    public List<List<Integer>>  backTrack(int[] nums, int idx) {
        if(idx == nums.length) {
            List<Integer> tempList = new ArrayList<>();
            for(int i = 0; i < nums.length; i++) tempList.add(nums[i]);
            if(!result.contains(tempList)) result.add(tempList);
        } else {
            for(int start = idx; start < nums.length; start++) {
                swap(nums, start, idx); 
                backTrack(nums, idx + 1);
                swap(nums, start, idx);
            }
        }
        return result;
    }
    
    public void swap(int[] nums, int idx, int start) {
        int temp = nums[idx];
        nums[idx] = nums[start];
        nums[start] = temp;
    }   
}

Solution in Python Programming

class Solution:
    def permuteUnique(self, nums):
        L = []
            
        def p(i):
            if i == len(nums):
                L.append(nums[:])

            for j in range(i, len(nums)):
                nums[i], nums[j] = nums[j], nums[i]
                p(i + 1)
                nums[i], nums[j] = nums[j], nums[i]
        
        p(0)
        
        L = list(set(map(lambda x : tuple(x),L)))
                
        return L

Solution in C# Programming

public class Solution 
{
    public IList<IList<int>> PermuteUnique(int[] nums) 
    {
        IList<IList<int>> solution = new List<IList<int>>();
        
        int n = nums.Length;
        
        Array.Sort(nums);
        
        Helper(solution, new List<int>(), n, nums, new bool[n]);
            
        return solution;
    }
    
    private void Helper(IList<IList<int>> solution, IList<int> currentPath, int n, int[] nums, bool[] visited)
    {
        if(currentPath.Count == n)
        {
            solution.Add(new List<int>(currentPath));
            return;
        }
        
        
        for(int i = 0; i < n; i++)
        {
            if(!visited[i])
            {
                currentPath.Add(nums[i]);
                visited[i] = true;
                Helper(solution, currentPath, n, nums, visited);
                currentPath.RemoveAt(currentPath.Count - 1);
                visited[i] = false;
                
                while(i < n - 1 && nums[i] == nums[i + 1])
                {
                    i++;
                }
                
            }
            
        }
    }
    
}

Also read,

By Neha Singhal

Hi, my name is Neha singhal a software engineer and coder by profession. I like to solve coding problems that give me the power to write posts for this site.

Leave a Reply

Your email address will not be published. Required fields are marked *