0% found this document useful (0 votes)
5 views3 pages

Time & Space Complexity - PERMUTATION

The document describes three different algorithms for generating unique permutations of an array: recursive backtracking using a count map, an iterative solution, and recursive backtracking using a visited array. Each method has a time complexity of O(N * N!) and a space complexity that varies depending on the approach. The recursive methods ensure uniqueness by tracking counts or using a visited array to avoid duplicates.

Uploaded by

NEEL SHAH
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views3 pages

Time & Space Complexity - PERMUTATION

The document describes three different algorithms for generating unique permutations of an array: recursive backtracking using a count map, an iterative solution, and recursive backtracking using a visited array. Each method has a time complexity of O(N * N!) and a space complexity that varies depending on the approach. The recursive methods ensure uniqueness by tracking counts or using a visited array to avoid duplicates.

Uploaded by

NEEL SHAH
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 3

Recursive Backtracking

/**
* Recursive Backtracking using countMap.
*
* Time Complexity: O(N * N!). Number of permutations = P(N,N) = N!. Each
* permutation takes O(N) to construct
*
* T(n) = n*T(n-1) + O(n)
* T(n-1) = (n-1)*T(n-2) + O(n)
* ...
* T(2) = (2)*T(1) + O(n)
* T(1) = O(n)
*
* Above equations can be added together to get:
* T(n) = n (1 + n + n*(n-1) + ... + (n....2) + (n....1))
* = n (P(n,0) + P(n,1) + P(n,1) + ... + P(n,n-1) + P(n,n))
* = n * Floor(e*n!)
* = O(N * N!)
*
* Space Complexity: O(N). Recursion stack + countMap + tempList
*
* N = Length of input array.
*/
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
if (nums == null || nums.length == 0) {
return result;
}

HashMap<Integer, Integer> countMap = new HashMap<>();


for (int n : nums) {
countMap.put(n, countMap.getOrDefault(n, 0) + 1);
}

permuteUniqueHelper(result, nums.length, countMap, new ArrayList<>());


return result;
}

private void permuteUniqueHelper(List<List<Integer>> result, int inputLength,


HashMap<Integer, Integer> countMap, List<Integer> tempList) {
if (tempList.size() == inputLength) {
result.add(new ArrayList<>(tempList));
return;
}
for (int num : countMap.keySet()) {
int count = countMap.get(num);
if (count == 0) {
continue;
}
countMap.put(num, count - 1);
tempList.add(num);
permuteUniqueHelper(result, inputLength, countMap, tempList);
tempList.remove(tempList.size() - 1);
countMap.put(num, count);
}
}
}
Iterative Solution

/**
* Iterative Solution
*
* The idea is to add the nth number in every possible position of each permutation
of the first n-1 numbers.
*
* Time Complexity: O(N * N!). Number of permutations = P(N,N) = N!. Each
permutation takes O(N) to construct
*
* T(n) = (x=2->n) ∑ (x-1)!*x(x+1)/2
* = (x=1->n-1) ∑ (x)!*x(x-1)/2
* = O(N * N!)
*
* Space Complexity: O((N-1) * (N-1)!) = O(N * N!). All permutations of the first
n-1 numbers.
*
* N = Length of input array.
*/
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
if (nums == null || nums.length == 0) {
return result;
}

result.add(Arrays.asList(nums[0]));

for (int i = 1; i < nums.length; i++) {


List<List<Integer>> newResult = new ArrayList<>();
for (List<Integer> cur : result) {
for (int j = 0; j <= i; j++) {
List<Integer> newCur = new ArrayList<>(cur);
newCur.add(j, nums[i]);
newResult.add(newCur);

// If number just added is same as the number at jth index of


cur list. Then we
// can break to avoid duplicates.
if (j < i && cur.get(j) == nums[i]) {
break;
}
}
}
result = newResult;
}

return result;
}
}
Recursive Backtracking using visited array

/**
* Recursive Backtracking using visited array.
*
* Time Complexity: O(N * N! + NlogN). Number of permutations = P(N,N) = N!.
* Each permutation takes O(N) to construct
*
* T(n) = n*T(n-1) + O(n)
* T(n-1) = (n-1)*T(n-2) + O(n)
* ...
* T(2) = (2)*T(1) + O(n)
* T(1) = O(n)
*
* Above equations can be added together to get:
* T(n) = n (1 + n + n*(n-1) + ... + (n....2) + (n....1))
* = n (P(n,0) + P(n,1) + P(n,1) + ... + P(n,n-1) + P(n,n))
* = n * Floor(e*n!)
* = O(N * N!)
*
* Space Complexity: O(N). Recursion stack + visited array + Sorting + tempList
*
* N = Length of input array.
*/
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
if (nums == null || nums.length == 0) {
return result;
}

Arrays.sort(nums);
permuteUniqueHelper(result, nums, new ArrayList<>(), new
boolean[nums.length]);
return result;
}

private void permuteUniqueHelper(List<List<Integer>> result, int[] nums,


List<Integer> tempList, boolean[] visited) {
if (tempList.size() == nums.length) {
result.add(new ArrayList<>(tempList));
return;
}
for (int i = 0; i < nums.length; i++) {
/**
* !visited[i - 1] is making sure that duplicate results are not added.
Since
* nums[i-1] and nums[i] are same, nums[i] can only be used if nums[i-
1] is
* currently in use.
*/
if (visited[i] || (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]))
{
continue;
}
visited[i] = true;
tempList.add(nums[i]);
permuteUniqueHelper(result, nums, tempList, visited);
tempList.remove(tempList.size() - 1);
visited[i] = false;
}
}
}

You might also like