Concepts Used

Back Tracking

Difficulty Level

Hard

Problem Statement :

Given N integers print all distinct combinations.

See original problem statement here

Solution Approach :

Introduction :

Idea is to swap all the values one-by-one and keep track of the values used. In a set of n elements with d similar elements there are n!/m! different permutations. For example, there are 3 permutations of the set {1,1,2}, namely [1,1,2], [1,2,1], [2,1,1].

Description:

We will use backtracking to solve the above problem referring some best online programming courses.
Backtracking is the approach to solve the problem by testing all possible answers (by breaking the problems into subproblems). If any subproblem does not fit the given constraint then we discard the complete subproblem (backtrack), moves a step back then try other remaining possible combinations. Backtracking algorithm is generally exponential in time.
Since it has duplicate items as well, we will keep track of the items already used, with the help of used[] array. Every time we see an unsed item we add it to used[] array. Now we will swap every index of the array, breaking our problem into subproblems by recursively calling our function for the next index, when the index becomes equal to the size of the array we print the current combination, every time we swap indices we make sure to revert the changes by swapping them back again to try another combinations (backtrack).

Algorithm :

backtracking():

  1. If index == n, print the current combination.
  2. else, for every k= index to n-1 :
    • if k is unused, add k to the used[] array
    • swap(index,k)
    • call backtrack(arr,index+1,n)
    • swap(index,k) , (Backtrack step).

Complexity Analysis :

Total number of permutations are, as discussed earlier, n!, and it takes O(n) time to print each permutation. Can you guess the final time complexity?

Solutions:


#include <bits/stdc++.h>
    using namespace std;

    bool checkduplicate(vector<int> t, int n){
            for(int i=0; i<t.size(); i++)
                if(t[i] == n) return true;
            return false;
        }

    void backtracking( vector<int> nums, int index){
            if(index == nums.size())
               {
                 for(auto i:nums)
                  cout<<i<<" ";
                  cout<<endl;
               }

            vector<int> t;
            for(int i=index; i<nums.size(); i++){
                if(checkduplicate(t, nums[i]))          // make sure nums[i] is not used
                    continue;
                t.push_back(nums[i]);                   // put all used items into vector t
                swap(nums[i], nums[index]);
                backtracking( nums, index+1);
                swap(nums[i], nums[index]);
            }
        }

    int main()
    {  

        int n;
      cin>>n;
      vector<int> v(n);
      int x;
      for(int i=0;i<n;i++)
      {
        cin>>v[i];

      }
      sort(v.begin(),v.end());

        backtracking(v, 0);


    return 0;
    }
import java.util.*;
import java.io.*;
public class Main {
  static ArrayList<String> Sarr=new ArrayList<String>();
  public static void main(String args[]) throws IOException {
    Scanner sc=new Scanner(System.in);
    int size=sc.nextInt();
    int[] arr=new int[size];
    int[] freq=new int[52];
    for(int i=0;i<size;i++){
      arr[i]=sc.nextInt();
      freq[arr[i]]++;
    }
    Arrays.sort(arr);
    backTracking(freq,arr,"",0);
  }
  static void backTracking(int[] freq,int[] arr,String res,int count){
    if(count==arr.length){
      if(!Sarr.contains(res)){
        System.out.println(res);
        Sarr.add(res);
      }
    }
    else{
      for(int i=0;i<arr.length;i++){
        if(freq[arr[i]]>0){
          freq[arr[i]]--;
          backTracking(freq,arr,res+arr[i]+" ",count+1);
          freq[arr[i]]++;
        }
      }
    }
  }
}
Previous post Grey Code
Next post Phone Number

Leave a Reply

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