DEV Community

Jaspreet singh
Jaspreet singh

Posted on

Permutations | Backtracking

Problem Statement

Given an array nums containing distinct integers, return all possible permutations.

A permutation is an arrangement of all elements in a different order.


Brute Force Intuition

For every position, try placing each available number.

Once a number is used, it cannot be used again in the same permutation.

We keep building the permutation until all positions are filled.

Since every possible arrangement must be generated, recursion naturally fits.

Complexity

  • Time Complexity: O(N! × N)
  • Space Complexity: O(N)

Moving Towards the Optimal Approach

At every level:

Choose one unused number
Enter fullscreen mode Exit fullscreen mode

Add it to the current permutation.

Mark it as visited.

Recurse for the next position.

After returning:

Undo the choice
Enter fullscreen mode Exit fullscreen mode

This is classic Backtracking.


Pattern Recognition

Whenever you see:

  • Generate all arrangements
  • Ordering matters
  • Every element used exactly once

Think:

Backtracking + Visited Array


Key Observation

For:

nums = [1,2,3]
Enter fullscreen mode Exit fullscreen mode

At Position 1:

Choose 1
Choose 2
Choose 3
Enter fullscreen mode Exit fullscreen mode

Each choice creates an entirely new branch.


Recursion Tree

[]

├── [1]
│   ├── [1,2]
│   │   └── [1,2,3]
│   │
│   └── [1,3]
│       └── [1,3,2]
│
├── [2]
│   ├── [2,1]
│   │   └── [2,1,3]
│   │
│   └── [2,3]
│       └── [2,3,1]
│
└── [3]
    ├── [3,1]
    │   └── [3,1,2]
    │
    └── [3,2]
        └── [3,2,1]
Enter fullscreen mode Exit fullscreen mode

Optimal Java Solution

import java.util.*;

class Solution {

    public List<List<Integer>> permute(int[] nums) {

        boolean[] visited = new boolean[nums.length];

        List<List<Integer>> ans = new ArrayList<>();

        solvePermute(nums,
                     visited,
                     ans,
                     new ArrayList<>());

        return ans;
    }

    private void solvePermute(int[] nums,
                              boolean[] visited,
                              List<List<Integer>> ans,
                              List<Integer> temp) {

        if (temp.size() == nums.length) {
            ans.add(new ArrayList<>(temp));
            return;
        }

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

            if (visited[i])
                continue;

            visited[i] = true;

            temp.add(nums[i]);

            solvePermute(nums,
                         visited,
                         ans,
                         temp);

            temp.remove(temp.size() - 1);

            visited[i] = false;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Dry Run

Input

nums = [1,2,3]
Enter fullscreen mode Exit fullscreen mode

Step 1

Choose:

1
Enter fullscreen mode Exit fullscreen mode

Current:

[1]
Enter fullscreen mode Exit fullscreen mode

Step 2

Choose:

2
Enter fullscreen mode Exit fullscreen mode

Current:

[1,2]
Enter fullscreen mode Exit fullscreen mode

Step 3

Choose:

3
Enter fullscreen mode Exit fullscreen mode

Current:

[1,2,3]
Enter fullscreen mode Exit fullscreen mode

Valid permutation

Backtrack and try other choices.


Output

[
 [1,2,3],
 [1,3,2],
 [2,1,3],
 [2,3,1],
 [3,1,2],
 [3,2,1]
]
Enter fullscreen mode Exit fullscreen mode

Why Backtracking Works?

At every position:

Try every unused number
Enter fullscreen mode Exit fullscreen mode

Once a choice is made:

Mark Used
Explore
Unmark Used
Enter fullscreen mode Exit fullscreen mode

This guarantees every permutation is generated exactly once.


Complexity Analysis

Metric Complexity
Time Complexity O(N! × N)
Space Complexity O(N)

Reason:

N! permutations exist
Enter fullscreen mode Exit fullscreen mode

and copying each permutation takes O(N).


Interview One-Liner

Build permutations by choosing one unused element at a time, marking it visited, recursively generating the remaining positions, and backtracking afterward.


Pattern Learned

Generate All Arrangements
+
Use Every Element Once

=> Backtracking
=> Visited Array
Enter fullscreen mode Exit fullscreen mode

Similar Problems

  • Permutations
  • Permutations II
  • N Queens
  • Sudoku Solver
  • Word Search
  • Rat in a Maze

Memory Trick

Subsets
→ Pick / Not Pick

Combination Sum
→ Pick / Not Pick + Reuse

Palindrome Partitioning
→ Try Every Cut

Permutations
→ Try Every Unused Element
Enter fullscreen mode Exit fullscreen mode

Mental Model

Current Position

Choose Any Unused Number
        ↓
Mark Used
        ↓
Recurse
        ↓
Backtrack
Enter fullscreen mode Exit fullscreen mode

Whenever you hear:

"Generate all permutations"

your brain should immediately think:

Backtracking + Visited Array + Choose Any Unused Element

Top comments (0)