Bird
Raised Fist0
Interview PrepbacktrackingmediumAmazonGoogleFacebook

Palindrome Partitioning

Choose your preparation mode4 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Steps
setup

Start Backtracking at index 0 with empty path

The algorithm begins by calling backtrack with start index 0 and an empty path to build palindrome partitions from the start of the string.

💡 This initializes the recursion and sets up the empty path that will be built up with palindrome substrings.
Line:backtrack(0, [])
💡 The recursion tree root represents the initial state before any substrings are chosen.
📊
Palindrome Partitioning - Watch the Algorithm Execute, Step by Step
Watching each recursive call and decision reveals how the algorithm systematically explores all partitions and prunes invalid paths, making the backtracking process clear and intuitive.
Step 1/16
·Active fillAnswer cell
enteringstart=0path=[]
Call Path (current → root)
backtrack(0, [])
Remaining
end=0end=1end=2
choosingstart=0path=[]
Call Path (current → root)
backtrack(0, [])
Remaining
end=1end=2
enteringstart=1path=["a"]
Call Path (current → root)
backtrack(1, ['a'])
backtrack(0, [])
Remaining
end=1end=2
Partial: [a]
choosingstart=1path=["a"]
Call Path (current → root)
backtrack(1, ['a'])
backtrack(0, [])
Remaining
end=2
Partial: [a]
enteringstart=2path=["a","a"]
Call Path (current → root)
backtrack(2, ['a', 'a'])
backtrack(1, ['a'])
backtrack(0, [])
Remaining
end=2
Partial: [a, a]
choosingstart=2path=["a","a"]
Call Path (current → root)
backtrack(2, ['a', 'a'])
backtrack(1, ['a'])
backtrack(0, [])
Partial: [a, a]
enteringstart=3path=["a","a","b"]
Call Path (current → root)
backtrack(3, ['a', 'a', 'b'])
backtrack(2, ['a', 'a'])
backtrack(1, ['a'])
backtrack(0, [])
Partial: [a, a, b]
backtrackingstart=3path=["a","a","b"]
Call Path (current → root)
backtrack(3, ['a', 'a', 'b'])
backtrack(2, ['a', 'a'])
backtrack(1, ['a'])
backtrack(0, [])
Partial: [a, a, b]
Found 1: [a,a,b]
choosingstart=2path=["a","a"]
Call Path (current → root)
backtrack(2, ['a', 'a'])
backtrack(1, ['a'])
backtrack(0, [])
Tried
end=2
Partial: [a, a]
Found 1: [a,a,b]
choosingstart=1path=["a"]
Call Path (current → root)
backtrack(1, ['a'])
backtrack(0, [])
Tried
end=1end=2
Partial: [a]
substring 'ab' is not palindrome
Found 1: [a,a,b]
choosingstart=0path=[]
Call Path (current → root)
backtrack(0, [])
Tried
end=0
Remaining
end=2
Found 1: [a,a,b]
enteringstart=2path=["aa"]
Call Path (current → root)
backtrack(2, ['aa'])
backtrack(0, [])
Remaining
end=2
Partial: [aa]
Found 1: [a,a,b]
choosingstart=2path=["aa"]
Call Path (current → root)
backtrack(2, ['aa'])
backtrack(0, [])
Partial: [aa]
Found 1: [a,a,b]
enteringstart=3path=["aa","b"]
Call Path (current → root)
backtrack(3, ['aa', 'b'])
backtrack(2, ['aa'])
backtrack(0, [])
Partial: [aa, b]
Found 1: [a,a,b]
backtrackingstart=3path=["aa","b"]
Call Path (current → root)
backtrack(3, ['aa', 'b'])
backtrack(2, ['aa'])
backtrack(0, [])
Partial: [aa, b]
Found 2: [a,a,b] [aa,b]
backtrackingstart=0path=[]
Call Path (current → root)
backtrack(0, [])
Tried
end=0end=2
Found 2: [a,a,b] [aa,b]

Key Takeaways

Backtracking systematically explores all substring partitions by recursively choosing palindromic substrings and backtracking to try alternatives.

This insight is hard to see from code alone because the recursion and backtracking flow is implicit and not linear.

Palindrome checks prune invalid branches early, preventing unnecessary recursion and improving efficiency.

Seeing the pruning visually clarifies why the algorithm avoids exploring non-palindromic substrings.

The recursion tree structure corresponds directly to partial palindrome partitions, with leaves representing complete valid partitions.

This concrete mapping helps understand how partial solutions build up and how answers are collected.

Practice

(1/5)
1. Consider the following Python code snippet implementing the optimal backtracking approach for Expression Add Operators. Given input num = "123" and target = 6, what is the content of the result list after the function completes?
from typing import List

def addOperators(num: str, target: int) -> List[str]:
    res = []
    path = []
    def backtrack(index: int, evaluated: int, last_operand: int):
        if index == len(num):
            if evaluated == target:
                res.append(''.join(path))
            return
        for i in range(index, len(num)):
            if i != index and num[index] == '0':
                break
            curr_str = num[index:i+1]
            curr = int(curr_str)
            length_before = len(path)
            if index == 0:
                path.append(curr_str)
                backtrack(i+1, curr, curr)
                path[length_before:] = []
            else:
                path.append('+'); path.append(curr_str)
                backtrack(i+1, evaluated + curr, curr)
                path[length_before:] = []
    backtrack(0, 0, 0)
    return res
easy
A. ["1+23", "12+3"]
B. ["123"]
C. ["1+2+3", "123"]
D. ["1+2+3"]

Solution

  1. Step 1: Trace backtracking calls for num="123", target=6

    At index=0, path starts with "1". Then at index=1, add '+' and "2", evaluated=3. Then at index=2, add '+' and "3", evaluated=6, matches target, so "1+2+3" is added.
  2. Step 2: Check other possible expressions

    "123" alone evaluates to 123, not 6. "1+23"=24, "12+3"=15, none equal 6. So only "1+2+3" is in result.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Only "1+2+3" sums to 6 [OK]
Hint: Only "1+2+3" equals 6 with given operators [OK]
Common Mistakes:
  • Assuming "123" or "1+23" equals target
2. What is the time complexity of the backtracking with bitmask optimization approach for counting beautiful arrangements of size n?
medium
A. O(n * n!)
B. O(n^2)
C. O(n * 2^n)
D. O(n!)

Solution

  1. Step 1: Identify the search space

    The algorithm explores permutations of n numbers, which is n! in worst case.
  2. Step 2: Consider pruning and bitmask usage

    Bitmask helps track used numbers efficiently, pruning invalid branches but the total number of recursive calls is proportional to n * n! because for each position, up to n choices are tried.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Backtracking explores permutations with n choices per position, leading to O(n * n!) complexity [OK]
Hint: Backtracking permutations with bitmask -> O(n * n!) time [OK]
Common Mistakes:
  • Confusing bitmask with exponential 2^n complexity
  • Assuming polynomial due to pruning
3. Identify the bug in the following code snippet for getPermutation:
medium
A. Line 6: k is not converted to zero-based index before calculations.
B. Line 2: factorial array initialization is incorrect.
C. Line 10: The index calculation uses integer division incorrectly.
D. Line 12: numbers.pop(idx) should be numbers.remove(idx).

Solution

  1. Step 1: Check k adjustment

    k must be decremented by 1 to convert to zero-based indexing before using factorial divisions.
  2. Step 2: Understand impact of missing k -= 1

    Without this, idx calculation is off by one, leading to incorrect permutation output.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Missing k -= 1 causes wrong indexing and wrong permutation [OK]
Hint: Always convert k to zero-based before factorial indexing [OK]
Common Mistakes:
  • Forgetting zero-based index adjustment
  • Misusing pop vs remove
  • Incorrect factorial initialization
4. What is the time complexity of the optimal backtracking with Trie approach for Word Search II, given a board of size MxN and a list of words with maximum length L? Assume the Trie is already built.
medium
A. O(M * N * 4 * 3^(L-1)) due to pruning and adjacency constraints
B. O(M * N * 4^L * W), where W is the number of words
C. O(M * N * L^2) because each cell explores all prefixes
D. O(M * N * L) since each cell is visited once per character

Solution

  1. Step 1: Identify branching factor in backtracking

    From each cell, up to 4 directions are possible initially, then up to 3 directions for subsequent steps due to no revisiting.
  2. Step 2: Calculate complexity with pruning

    Trie pruning reduces unnecessary paths, so complexity is roughly O(M * N * 4 * 3^(L-1)) where L is max word length.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Matches known complexity from Trie + backtracking analysis [OK]
Hint: Branching factor reduces after first step due to visited constraints [OK]
Common Mistakes:
  • Confusing W (number of words) as multiplicative factor in optimal approach.
5. Suppose you want to find the lexicographically next permutation of an array where elements can be repeated and reused multiple times (infinite supply). Which modification to the standard next permutation algorithm is necessary?
hard
A. No modification needed; the standard next permutation algorithm works as is.
B. Modify the algorithm to generate all permutations with repetition and pick the next one, since in-place approach fails.
C. Adjust the pivot search to consider repeated elements and skip duplicates to avoid redundant swaps.
D. Use a backtracking approach that allows repeated elements and generates permutations with repetition.

Solution

  1. Step 1: Understand the problem variant

    Allowing repeated use of elements means permutations with repetition, which standard next permutation does not handle as it assumes fixed elements.
  2. Step 2: Identify correct approach

    Backtracking that generates permutations with repetition is required, as in-place next permutation only rearranges existing elements without reuse.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Standard next permutation assumes fixed elements; repeated reuse requires backtracking [OK]
Hint: Next permutation assumes fixed elements; reuse needs backtracking [OK]
Common Mistakes:
  • Thinking standard algorithm handles reuse
  • Trying to modify pivot logic only