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

    Graphs and dynamic programming · Lesson 22 of 23

    DP on grids and strings

    A `dp[i][j]` table: grid paths, longest common subsequence and the knapsack.

    15 minutes2 games

    When a state needs two numbers, the table becomes two-dimensional: dp[i][j]. The three classic shapes:

    • Grid: dp[r][c] = the answer up to this cell (from above and the left).
    • Two strings: dp[i][j] = the answer for the first i letters of one and first j of the other.
    • Choices with a limit: dp[i][c] = the answer with the first i items and capacity c (knapsack).
    JavaScript
    // Grid: number of right/down paths from the top-left to the bottom-right
    function gridPaths(rows, cols) {
      const dp = Array.from({ length: rows }, () => new Array(cols).fill(1))
      for (let r = 1; r < rows; r++)
        for (let c = 1; c < cols; c++) dp[r][c] = dp[r - 1][c] + dp[r][c - 1]
      return dp[rows - 1][cols - 1]
    }
    
    // Two strings: longest common subsequence
    function lcs(a, b) {
      const dp = Array.from({ length: a.length + 1 }, () => new Array(b.length + 1).fill(0))
      for (let i = 1; i <= a.length; i++)
        for (let j = 1; j <= b.length; j++)
          dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] + 1 : Math.max(dp[i - 1][j], dp[i][j - 1])
      return dp[a.length][b.length]
    }
    
    console.log(gridPaths(3, 7), lcs("abcde", "ace"), lcs("seacode", "decode"))
    ""ace

    ""

    0

    0

    0

    0

    a

    0

    1

    1

    1

    b

    0

    1

    1

    1

    c

    0

    1

    2

    2

    d

    0

    1

    2

    2

    e

    0

    1

    2

    3

    The LCS table for abcde and ace. Matching letters take the diagonal + 1; otherwise the larger of above and left. The answer sits in the last cell: 3.

    The 0/1 knapsack

    JavaScript
    // best[c] = most value with capacity c using the items seen so far.
    // Looping capacity downward keeps each item to a single use.
    function knapsack(weights, values, capacity) {
      const best = new Array(capacity + 1).fill(0)
      for (let i = 0; i < weights.length; i++)
        for (let c = capacity; c >= weights[i]; c--)
          best[c] = Math.max(best[c], best[c - weights[i]] + values[i])
      return best[capacity]
    }
    
    console.log(knapsack([1, 3, 4, 5], [1, 4, 5, 7], 7))

    Important

    A small change alters the meaning: in the knapsack, looping capacity upward instead of downward lets an item be taken more than once (the unbounded knapsack, like coins). And when each row depends only on the previous one, keep one or two rows: memory drops from O(m·n) to O(n).

    What's the output?

    const dp = [[1, 1, 1], [1, 0, 0], [1, 0, 0]]
    for (let r = 1; r < 3; r++)
      for (let c = 1; c < 3; c++) dp[r][c] = dp[r - 1][c] + dp[r][c - 1]
    console.log(dp[2][2])

    What will this code print?

    Interview question

    Explain edit distance: the fewest insert/delete/replace operations turning one word into another.

    Exercise

    Write minPath(grid): the smallest sum from the top-left to the bottom-right moving only right or down. It must print 7 12.

    Expected output: 7 12

    JavaScript
    function minPath(grid) {
      
    }
    
    console.log(minPath([[1, 3, 1], [1, 5, 1], [4, 2, 1]]), minPath([[1, 2, 3], [4, 5, 6]]))

    Practise on real problems

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

    • Paths through a gridMedium
    • Minimum path sumMedium
    • Grid paths with obstaclesMedium
    • Longest common subsequenceMedium
    • Edit distanceHard
    • 0/1 knapsackMedium
    • Partition into equal sumsMedium
    • Word breakMedium

    Learn more from

    • Wikipedia: Longest common subsequenceen.wikipedia.org
    • Wikipedia: Knapsack problemen.wikipedia.org
    • Wikipedia: Levenshtein distanceen.wikipedia.org
    • MIT OpenCourseWare: Introduction to Algorithms (6.006)ocw.mit.edu

    Played 0 of 2 games

    Sign in to save your progress and earn XP.

    PreviousDynamic programming: the ideaNextGreedy: the best choice right now
    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.