Bird
Raised Fist0
Interview PrepbacktrackingmediumAmazonMicrosoftGoogleBloomberg

Permutations

Choose your preparation mode4 modes available
📋
Problem

Imagine you are organizing a race and want to list all possible orders in which runners can finish. How many ways can you arrange them, and how do you generate each order?

Given an array of distinct integers nums, return all possible permutations. You can return the answer in any order. Input: An array nums of distinct integers. Output: A list of lists, where each list is a unique permutation of nums.

1 ≤ nums.length ≤ 8All elements of nums are distinct integers
Edge cases: Empty array → [] (no permutations)Single element array → [[element]] (only one permutation)Array with two elements → two permutations swapping order
</>
IDE
def permute(nums: list[int]) -> list[list[int]]:public List<List<Integer>> permute(int[] nums)vector<vector<int>> permute(vector<int>& nums)function permute(nums)
def permute(nums):
    # Write your solution here
    pass
class Solution {
    public List<List<Integer>> permute(int[] nums) {
        // Write your solution here
        return new ArrayList<>();
    }
}
#include <vector>
using namespace std;

vector<vector<int>> permute(vector<int>& nums) {
    // Write your solution here
    return {};
}
function permute(nums) {
    // Write your solution here
}
0/9
Common Bugs to Avoid
Wrong: [[1,2,3],[1,3,2],[2,1,3]]Greedy approach that stops recursion early or picks only first unused element.✅ In backtracking, loop over all unused elements at each recursion level instead of picking first only.
Wrong: [[1,1,1],[1,1,1],[1,1,1]]Reusing elements multiple times in the same permutation (unbounded instead of 0/1).✅ Use a used array to mark elements as used and prevent reuse in the same path.
Wrong: [[]]Returning a list with an empty permutation for empty input instead of empty list.✅ Return [] immediately if input is empty; do not add empty path as a permutation.
Wrong: [[4,5]]Not exploring all permutations for two elements; missing swapped order.✅ Ensure recursion explores all unused elements at each step.
✓
Test Cases
t1_01basic
Input{"nums":[1,2,3]}
Expected[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

All 6 permutations of the array [1,2,3] are generated by swapping elements recursively.

t1_02basic
Input{"nums":[4,5]}
Expected[[4,5],[5,4]]

Two elements produce two permutations by swapping their order.

t2_01edge
Input{"nums":[]}
Expected[]

Empty array has no permutations.

t2_02edge
Input{"nums":[7]}
Expected[[7]]

Single element array has exactly one permutation: itself.

t2_03edge
Input{"nums":[1,2,3,4,5,6,7,8]}
Expectednull

Maximum length input with 8 distinct elements; factorial(8)=40320 permutations expected.

t3_01corner
Input{"nums":[1,2,2]}
Expected[]

Input contains duplicates which violates problem constraints of distinct integers; no valid permutations expected.

t3_02corner
Input{"nums":[1,2,3]}
Expected[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

Test to catch greedy approach that picks first unused element always, missing permutations.

t3_03corner
Input{"nums":[1,2,3]}
Expected[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

Test to catch confusion between 0/1 and unbounded permutations (reusing elements).

t4_01performance
Input{"nums":[1,2,3,4,5,6,7,8]}
⏱ Performance - must finish in 2000ms

Input size n=8; algorithm must handle O(n! * n) complexity within 2 seconds.

Practice

(1/5)
1. You are given a numeric string and a target integer. You need to insert binary operators (+, -, *) between digits to form expressions that evaluate to the target. Which algorithmic approach guarantees finding all valid expressions efficiently while handling operator precedence and avoiding invalid operands like those with leading zeros?
easy
A. Backtracking with pruning and careful operand parsing to explore all operator insertions
B. Breadth-first search enumerating all possible expressions without pruning
C. Dynamic programming that stores sub-expression results without operator precedence handling
D. Greedy approach that inserts operators at fixed intervals without backtracking

Solution

  1. Step 1: Understand problem requirements

    The problem requires exploring all ways to insert operators to reach a target, respecting operator precedence and avoiding invalid operands like those with leading zeros.
  2. Step 2: Identify suitable algorithm

    Backtracking with pruning and operand parsing systematically explores all valid expressions, correctly handles precedence (especially multiplication), and prunes invalid paths early.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Backtracking explores all valid expressions with pruning [OK]
Hint: Backtracking explores all operator insertions with pruning [OK]
Common Mistakes:
  • Assuming greedy or DP can handle operator precedence and invalid operands
2. You are given a 2D grid of letters and a list of words. You need to find all words that can be formed by sequentially adjacent letters (horizontally or vertically) without reusing the same cell in a single word. Which algorithmic approach best guarantees an efficient solution for this problem?
easy
A. Use dynamic programming to store subproblems of partial word matches.
B. Use a greedy search that picks the next letter with the highest frequency in the grid.
C. Use backtracking combined with a Trie data structure to prune invalid prefixes early.
D. Search each word independently using DFS without any prefix pruning.

Solution

  1. Step 1: Understand problem constraints

    The problem requires searching multiple words in a grid with adjacency and no reuse constraints, which is expensive if done naively.
  2. Step 2: Identify efficient pruning technique

    Backtracking with a Trie allows pruning search paths early when no word prefix matches, avoiding redundant searches.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Trie pruning reduces search space drastically compared to naive DFS [OK]
Hint: Trie + backtracking prunes invalid prefixes early [OK]
Common Mistakes:
  • Thinking greedy or DP alone can solve adjacency constraints efficiently.
3. You are given a 2D grid of characters and a target string. You need to determine if the string can be formed by sequentially adjacent cells (horizontally or vertically) without revisiting any cell. Which algorithmic approach best guarantees an optimal solution for this problem?
easy
A. Backtracking with in-place marking and exploring all four directions
B. Dynamic Programming with memoization to store partial matches
C. Greedy search by always choosing the next matching character closest to the start
D. Breadth-first search (BFS) to explore all possible paths simultaneously

Solution

  1. Step 1: Understand problem constraints

    The problem requires checking if a word can be formed by adjacent cells without reuse, which is a classic backtracking scenario.
  2. Step 2: Identify suitable algorithm

    Backtracking with in-place marking efficiently explores all paths while preventing revisiting cells, guaranteeing correctness and optimal pruning.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Backtracking explores all valid paths with pruning [OK]
Hint: Backtracking fits adjacency and no-reuse constraints [OK]
Common Mistakes:
  • Assuming greedy or DP can solve adjacency constraints optimally
4. Consider the following code snippet implementing the optimal backtracking solution for Word Search. Given the board = [["A","B","C"],["D","E","F"],["G","H","I"]] and word = "BEF", what is the return value of exist(board, word)?
easy
A. True
B. False
C. Raises IndexError
D. Infinite recursion

Solution

  1. Step 1: Trace dfs starting at cell (0,1) 'B'

    Word starts with 'B', found at (0,1). dfs(0,1,0) matches 'B'.
  2. Step 2: Explore neighbors for next chars 'E' and 'F'

    From (0,1), neighbors checked: (1,1) 'E' matches next char, then (1,2) 'F' matches last char. All matched, return True.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    All characters found sequentially with valid moves [OK]
Hint: Trace dfs calls carefully to confirm path exists [OK]
Common Mistakes:
  • Assuming no path due to adjacency confusion
  • Missing in-place marking effect
5. What is the time complexity of the optimal in-place next permutation algorithm for an input array of length n?
medium
A. O(n) because it scans the array a constant number of times
B. O(n log n) because it sorts the suffix after the pivot
C. O(n!) due to generating all permutations
D. O(n^2) because it swaps elements multiple times in nested loops

Solution

  1. Step 1: Identify the main operations

    The algorithm scans from the end to find the pivot (O(n)), then scans again to find the swap element (O(n)), and finally reverses the suffix (O(n)).
  2. Step 2: Sum up the operations

    All steps are linear scans or swaps, so total time complexity is O(n).
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    No sorting or factorial generation involved, linear scans only [OK]
Hint: Next permutation scans array linearly multiple times [OK]
Common Mistakes:
  • Confusing suffix reversal with sorting
  • Assuming factorial due to permutations
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard