Skip to content
    SeaCode
    Learning tracksCode ArenaWorkshops & EventsInstructors
    Log inSign up
    DSADSA

    Foundations: measuring code

    • Big-O: how code grows
    • Space and the time–memory trade-off
    • Arrays and strings under the hood
    • Hash maps and sets
    • How to approach any interview problem

    Array patterns

    • Two pointers
    • Sliding window
    • Prefix sums
    • Binary search, done right
    • Sorting: merge sort and quicksort

    Stacks, queues and linked lists

    • Stacks and monotonic stacks
    • Queues and deques
    • Linked lists

    Recursion and trees

    • Recursion without fear
    • Backtracking: try and undo
    • Binary trees
    • Binary search trees
    • Heaps and priority queues

    Graphs and dynamic programming

    • Graphs: BFS and DFS
    • Shortest paths, topological sort and union-find
    • Dynamic programming: the idea
    • DP on grids and strings
    • Greedy: the best choice right now
    DSA

    Recursion and trees · Lesson 15 of 23

    Backtracking: try and undo

    One template for every "all possibilities" problem: subsets, permutations and combinations.

    14 minutes2 games

    When a problem asks for "all ways" or "all combinations", the answer is usually backtracking: build the answer step by step, try a choice at each step, continue, then undo it and try the next. Like walking a maze: at a dead end, go back to the last junction.

    JavaScript
    function backtrack(path, choices) {
      if (/* path is a complete answer */ false) { results.push([...path]); return }
      for (const choice of choices) {
        if (/* choice isn't allowed */ false) continue
        path.push(choice)          // choose
        backtrack(path, choices)   // explore
        path.pop()                 // un-choose
      }
    }
    JavaScript
    // All subsets: at each element, take it or leave it
    function subsets(nums) {
      const out = []
      const go = (i, path) => {
        if (i === nums.length) { out.push([...path]); return }
        path.push(nums[i]); go(i + 1, path); path.pop()   // take nums[i]
        go(i + 1, path)                                   // leave nums[i]
      }
      go(0, [])
      return out
    }
    
    // All orderings: pick any unused element next
    function permutations(nums) {
      const out = [], used = new Array(nums.length).fill(false)
      const go = (path) => {
        if (path.length === nums.length) { out.push([...path]); return }
        for (let i = 0; i < nums.length; i++) {
          if (used[i]) continue
          used[i] = true; path.push(nums[i])
          go(path)
          path.pop(); used[i] = false
        }
      }
      go([])
      return out
    }
    
    console.log(subsets([1, 2, 3]).length, permutations([1, 2, 3]).length)
    console.log(permutations([1, 2, 3]).map((p) => p.join("")).join(" "))
    • []
      • [1]
        • [1, 2]
          • [1, 2, 3]
          • [1, 2]
        • [1]
          • [1, 3]
          • [1]
      • []
        • [2]
        • []

    The subsets decision tree: each level is "take or leave" one element. The leaves are the answers (2ⁿ leaves).

    Important

    The key line is the undo (path.pop()). Forget it and old choices linger in the path. Also store a copy [...path], never path itself, since the same array keeps changing. The cost is exponential (2ⁿ or n!), so these problems come with small n (≤ 10–20). Pruning (stopping early on a hopeless branch) is what makes them fast.

    Spot the bug

    This returns the right number of subsets, but every one comes out empty []. Which line is wrong?

    Interview question

    How do you avoid duplicate combinations when the input has repeats (like [1, 2, 2])?

    Exercise

    Write combine(n, k): every combination of k numbers from 1 to n (ascending within each). It must print 6 12 34.

    Expected output: 6 12 34

    JavaScript
    function combine(n, k) {
      
    }
    
    const all = combine(4, 2)
    console.log(all.length, all[0].join(""), all[all.length - 1].join(""))

    Practise on real problems

    Practice problems that use what you learned here. Solve them in JavaScript, Python or C++.

    • All subsetsMedium
    • All permutationsMedium
    • Combination sumMedium
    • Generate parenthesesMedium
    • Phone number lettersMedium
    • Word searchMedium
    • Palindrome partitioningMedium
    • N-queens countHard

    Learn more from

    • Wikipedia: Backtrackingen.wikipedia.org
    • Wikipedia: Eight queens puzzleen.wikipedia.org
    • Tech Interview Handbook: Recursion cheatsheettechinterviewhandbook.org

    Played 0 of 2 games

    Sign in to save your progress and earn XP.

    PreviousRecursion without fearNextBinary trees
    SeaCode

    Learn to code for real, online or at our branch in front of Cairo University, Giza.

    Learn

    • All courses
    • Interactive tutorials
    • Interview practice problems
    • Mock interview
    • Learning tracks
    • Code Arena
    • Workshops & Events
    • Knowledge library
    • Team projects

    Your account

    • Log in
    • Sign up
    • Learning plan
    • Certificates
    • Site map

    Contact us

    • WhatsApp
    • 010 9094 1104
    • In front of Cairo University, Giza

    © 2026 SeaCode. All rights reserved.