From 5b6a33088c5f951d7169b4f749d39937e7586bd5 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 28 Sep 2026 13:57:07 -0400 Subject: [PATCH] feat(work): add Minimum Path Sum & Longest Common Subsequence solutions; refactor Unique Paths DP implementation --- .../1143-longest-common-subsequence.mdx | 49 +++++++++++++++ .../multi-d-grid-dp/62-unique-paths.mdx | 19 +++--- .../multi-d-grid-dp/64-minimum-path-sum.mdx | 53 ++++++++++++++++ .../guides/longest-common-subsequence.mdx | 8 +++ apps/docs/redirects.ts | 2 + work/1/Medium/Array/64.minimum-path-sum.py | 61 ++++++++++++++++++ work/1/Medium/Math/62.unique-paths.py | 19 +++--- .../String/1143.longest-common-subsequence.py | 63 +++++++++++++++++++ 8 files changed, 260 insertions(+), 14 deletions(-) create mode 100644 apps/docs/content/(05-decision-space)/multi-d-grid-dp/1143-longest-common-subsequence.mdx create mode 100644 apps/docs/content/(05-decision-space)/multi-d-grid-dp/64-minimum-path-sum.mdx create mode 100644 apps/docs/content/guides/longest-common-subsequence.mdx create mode 100644 work/1/Medium/Array/64.minimum-path-sum.py create mode 100644 work/1/Medium/String/1143.longest-common-subsequence.py diff --git a/apps/docs/content/(05-decision-space)/multi-d-grid-dp/1143-longest-common-subsequence.mdx b/apps/docs/content/(05-decision-space)/multi-d-grid-dp/1143-longest-common-subsequence.mdx new file mode 100644 index 0000000..d1c4461 --- /dev/null +++ b/apps/docs/content/(05-decision-space)/multi-d-grid-dp/1143-longest-common-subsequence.mdx @@ -0,0 +1,49 @@ +--- +title: '1143. Longest Common Subsequence' +description: Given two strings text1 and text2, return the length of their longest common subsequence. If there is no common subsequence, return 0 +icon: dot +topics: + - { name: "String", slug: "string" } + - { name: "Dynamic Programming", slug: "dynamic-programming" } + - { name: "Longest Common Subsequence", slug: "longest-common-subsequence" } +sidebar: + label: 'Longest Common Subsequence' + badge: 'Medium' +--- + +### Example 1: +- Input: `text1 = "abcde", text2 = "ace"` +- Output: `3` +- Explanation: The longest common subsequence is "ace" and its length is `3`. + +### Example 2: +- Input: `text1 = "abc", text2 = "abc"` +- Output: `3` +- Explanation: The longest common subsequence is "abc" and its length is `3`. + +### Example 3: +- Input: `text1 = "abc", text2 = "def"` +- Output: `0` +- Explanation: There is no such common subsequence, so the result is `0`. + +### Constraints: + +- `1 <= text1.length, text2.length <= 1000` +- `text1` and `text2` consist of only lowercase English characters. + +## Solution + +```py +class Solution: + def longestCommonSubsequence(self, text1: str, text2: str) -> int: + dp = [[0 for j in range(len(text2) + 1)] for i in range(len(text1) + 1)] + + for i in range(len(text1) - 1, -1, -1): + for j in range(len(text2) - 1, -1, -1): + if text1[i] == text2[j]: + dp[i][j] = 1 + dp[i + 1][j + 1] + else: + dp[i][j] = max(dp[i][j + 1], dp[i + 1][j]) + + return dp[0][0] +``` diff --git a/apps/docs/content/(05-decision-space)/multi-d-grid-dp/62-unique-paths.mdx b/apps/docs/content/(05-decision-space)/multi-d-grid-dp/62-unique-paths.mdx index aa659c7..4d0b730 100644 --- a/apps/docs/content/(05-decision-space)/multi-d-grid-dp/62-unique-paths.mdx +++ b/apps/docs/content/(05-decision-space)/multi-d-grid-dp/62-unique-paths.mdx @@ -29,12 +29,17 @@ sidebar: ```py class Solution: def uniquePaths(self, m: int, n: int) -> int: - row = [1] * n + dp = [[0 for _ in range(n)] for _ in range(m)] - for i in range(m - 1): - newRow = [1] * n - for j in range(n - 2, -1, -1): - newRow[j] = newRow[j + 1] + row[j] - row = newRow - return row[0] + for c in range(n): + dp[0][c] = 1 + + for r in range(m): + dp[r][0] = 1 + + for r in range(1, m): + for c in range(1, n): + dp[r][c] = dp[r - 1][c] + dp[r][c - 1] + + return dp[-1][-1] ``` diff --git a/apps/docs/content/(05-decision-space)/multi-d-grid-dp/64-minimum-path-sum.mdx b/apps/docs/content/(05-decision-space)/multi-d-grid-dp/64-minimum-path-sum.mdx new file mode 100644 index 0000000..5c98023 --- /dev/null +++ b/apps/docs/content/(05-decision-space)/multi-d-grid-dp/64-minimum-path-sum.mdx @@ -0,0 +1,53 @@ +--- +title: '64. Minimum Path Sum' +description: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right, which minimizes the sum of all numbers along its path +icon: dot +topics: + - { name: "Array", slug: "array" } + - { name: "Dynamic Programming", slug: "dynamic-programming" } + - { name: "Matrix", slug: "matrix" } +sidebar: + label: 'Minimum Path Sum' + badge: 'Medium' +--- + +### Example 1: +- Input: `grid = [[1,3,1],[1,5,1],[4,2,1]]` +- Output: `7` +- Explanation: Because the path `1` → `3` → `1` → `1` → `1` minimizes the sum. + +### Example 2: +- Input: `grid = [[1,2,3],[4,5,6]]` +- Output: `12` + +### Constraints: + +- `m == grid.length` +- `n == grid[i].length` +- `1 <= m, n <= 200` +- `0 <= grid[i][j] <= 200` + +## Solution + +```py +class Solution: + def minPathSum(self, grid: list[list[int]]) -> int: + if not grid or not grid[0]: + return 0 + + m = len(grid) + n = len(grid[0]) + dp = [[0 for _ in range(n)] for _ in range(m)] + + for c in range(n): + dp[0][c] = dp[0][c - 1] + grid[0][c] if c else grid[0][c] + + for r in range(m): + dp[r][0] = dp[r - 1][0] + grid[r][0] if r else grid[r][0] + + for r in range(1, m): + for c in range(1, n): + dp[r][c] = min(dp[r - 1][c], dp[r][c - 1]) + grid[r][c] + + return dp[-1][-1] +``` diff --git a/apps/docs/content/guides/longest-common-subsequence.mdx b/apps/docs/content/guides/longest-common-subsequence.mdx new file mode 100644 index 0000000..f6df2d4 --- /dev/null +++ b/apps/docs/content/guides/longest-common-subsequence.mdx @@ -0,0 +1,8 @@ +--- +title: "Longest Common Subsequence" +list: "https://leetcode.com/problem-list/longest-common-subsequence/" +--- + +:::note +This guide has not been written yet. The LeetCode list above has every problem tagged Longest Common Subsequence. +::: diff --git a/apps/docs/redirects.ts b/apps/docs/redirects.ts index c922964..fc48264 100644 --- a/apps/docs/redirects.ts +++ b/apps/docs/redirects.ts @@ -17,6 +17,7 @@ export default [ { from: "/49", to: "/hash-table/group-anagrams" }, { from: "/54", to: "/matrix-index-math/spiral-matrix" }, { from: "/62", to: "/multi-d-grid-dp/unique-paths" }, + { from: "/64", to: "/multi-d-grid-dp/minimum-path-sum" }, { from: "/70", to: "/1d-dynamic-programming/climbing-stairs" }, { from: "/73", to: "/matrix-index-math/set-matrix-zeroes" }, { from: "/74", to: "/binary-search/search-a-2d-matrix" }, @@ -70,6 +71,7 @@ export default [ { from: "/973", to: "/heap-priority-queue/k-closest-points-to-origin" }, { from: "/977", to: "/two-pointers/squares-of-a-sorted-array" }, { from: "/994", to: "/graph-bfs/rotting-oranges" }, + { from: "/1143", to: "/multi-d-grid-dp/longest-common-subsequence" }, { from: "/1448", to: "/tree-bfs/count-good-nodes-in-binary-tree" }, { from: "/1832", to: "/hash-table/check-if-the-sentence-is-pangram" }, ]; diff --git a/work/1/Medium/Array/64.minimum-path-sum.py b/work/1/Medium/Array/64.minimum-path-sum.py new file mode 100644 index 0000000..c242d91 --- /dev/null +++ b/work/1/Medium/Array/64.minimum-path-sum.py @@ -0,0 +1,61 @@ +""" +64. Minimum Path Sum +Difficulty: Medium +https://leetcode.com/problems/minimum-path-sum/ + +────────────────────────────────────────────────── + +Given a m x n grid filled with non-negative numbers, find a path from +top left to bottom right, which minimizes the sum of all numbers along +its path. + +Note: You can only move either down or right at any point in time. + + + +Example 1: + +Input: grid = [[1,3,1],[1,5,1],[4,2,1]] +Output: 7 +Explanation: Because the path 1 → 3 → 1 → 1 → 1 +minimizes the sum. + +Example 2: + +Input: grid = [[1,2,3],[4,5,6]] +Output: 12 + + + +Constraints: + + • m == grid.length + + • n == grid[i].length + + • 1 <= m, n <= 200 + + • 0 <= grid[i][j] <= 200 +""" + + +class Solution: + def minPathSum(self, grid: list[list[int]]) -> int: + if not grid or not grid[0]: + return 0 + + m = len(grid) + n = len(grid[0]) + dp = [[0 for _ in range(n)] for _ in range(m)] + + for c in range(n): + dp[0][c] = dp[0][c - 1] + grid[0][c] if c else grid[0][c] + + for r in range(m): + dp[r][0] = dp[r - 1][0] + grid[r][0] if r else grid[r][0] + + for r in range(1, m): + for c in range(1, n): + dp[r][c] = min(dp[r - 1][c], dp[r][c - 1]) + grid[r][c] + + return dp[-1][-1] diff --git a/work/1/Medium/Math/62.unique-paths.py b/work/1/Medium/Math/62.unique-paths.py index 8c36c7c..a047d25 100644 --- a/work/1/Medium/Math/62.unique-paths.py +++ b/work/1/Medium/Math/62.unique-paths.py @@ -43,11 +43,16 @@ Constraints: class Solution: def uniquePaths(self, m: int, n: int) -> int: - row = [1] * n + dp = [[0 for _ in range(n)] for _ in range(m)] - for i in range(m - 1): - newRow = [1] * n - for j in range(n - 2, -1, -1): - newRow[j] = newRow[j + 1] + row[j] - row = newRow - return row[0] + for c in range(n): + dp[0][c] = 1 + + for r in range(m): + dp[r][0] = 1 + + for r in range(1, m): + for c in range(1, n): + dp[r][c] = dp[r - 1][c] + dp[r][c - 1] + + return dp[-1][-1] diff --git a/work/1/Medium/String/1143.longest-common-subsequence.py b/work/1/Medium/String/1143.longest-common-subsequence.py new file mode 100644 index 0000000..36121de --- /dev/null +++ b/work/1/Medium/String/1143.longest-common-subsequence.py @@ -0,0 +1,63 @@ +""" +1143. Longest Common Subsequence +Difficulty: Medium +https://leetcode.com/problems/longest-common-subsequence/ + +────────────────────────────────────────────────── + +Given two strings text1 and text2, return the length of their longest +common subsequence. If there is no common subsequence, return 0. + +A subsequence of a string is a new string generated from the original +string with some characters (can be none) deleted without changing the +relative order of the remaining characters. + + • For example, "ace" is a subsequence of "abcde". + +A common subsequence of two strings is a subsequence that is common +to both strings. + + + +Example 1: + +Input: text1 = "abcde", text2 = "ace" +Output: 3 +Explanation: The longest common subsequence is "ace" and its length +is 3. + +Example 2: + +Input: text1 = "abc", text2 = "abc" +Output: 3 +Explanation: The longest common subsequence is "abc" and its length +is 3. + +Example 3: + +Input: text1 = "abc", text2 = "def" +Output: 0 +Explanation: There is no such common subsequence, so the result is 0. + + + +Constraints: + + • 1 <= text1.length, text2.length <= 1000 + + • text1 and text2 consist of only lowercase English characters. +""" + + +class Solution: + def longestCommonSubsequence(self, text1: str, text2: str) -> int: + dp = [[0 for j in range(len(text2) + 1)] for i in range(len(text1) + 1)] + + for i in range(len(text1) - 1, -1, -1): + for j in range(len(text2) - 1, -1, -1): + if text1[i] == text2[j]: + dp[i][j] = 1 + dp[i + 1][j + 1] + else: + dp[i][j] = max(dp[i][j + 1], dp[i + 1][j]) + + return dp[0][0]