{"id":832,"date":"2025-08-04T12:39:38","date_gmt":"2025-08-04T07:09:38","guid":{"rendered":"https:\/\/codeanddebug.in\/blog\/?p=832"},"modified":"2025-08-04T12:39:42","modified_gmt":"2025-08-04T07:09:42","slug":"triangle","status":"publish","type":"post","link":"https:\/\/codeanddebug.in\/blog\/triangle\/","title":{"rendered":"Triangle | Leetcode 120 | All 4 DP Solutions"},"content":{"rendered":"\n<p>Given a&nbsp;<code>triangle<\/code>&nbsp;array, return&nbsp;<em>the minimum path sum from top to bottom<\/em>.<\/p>\n\n\n\n<p>For each step, you may move to an adjacent number of the row below. More formally, if you are on index&nbsp;<code>i<\/code>&nbsp;on the current row, you may move to either index&nbsp;<code>i<\/code>&nbsp;or index&nbsp;<code>i + 1<\/code>&nbsp;on the next row.<\/p>\n\n\n\n<p>Here&#8217;s the [<strong><a href=\"https:\/\/leetcode.com\/problems\/triangle\/description\/\" target=\"_blank\" rel=\"noreferrer noopener\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"><span style=\"text-decoration: underline;\">Problem Link<\/span><\/mark><\/a><\/strong>] to begin with.<\/p>\n\n\n\n<p><strong>Example 1:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Input:<\/strong> triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]<br><strong>Output:<\/strong> 11<br><strong>Explanation:<\/strong> The triangle looks like:<br>   2<br>  3 4<br> 6 5 7<br>4 1 8 3<br>The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).<\/pre>\n\n\n\n<p><strong>Example 2:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Input:<\/strong> triangle = [[-10]]<br><strong>Output:<\/strong> -10<\/pre>\n\n\n\n<p><strong>Constraints:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>1 &lt;= triangle.length &lt;= 200<\/code><\/li>\n\n\n\n<li><code>triangle[0].length == 1<\/code><\/li>\n\n\n\n<li><code>triangle[i].length == triangle[i - 1].length + 1<\/code><\/li>\n\n\n\n<li><code>-10<sup>4<\/sup> &lt;= triangle[i][j] &lt;= 10<sup>4<\/sup><\/code><\/li>\n<\/ul>\n\n\n\n<p><strong>Follow up:<\/strong>&nbsp;Could you&nbsp;do this using only&nbsp;<code>O(n)<\/code>&nbsp;extra space, where&nbsp;<code>n<\/code>&nbsp;is the total number of rows in the triangle?<\/p>\n\n\n<div class=\"wp-block-ub-table-of-contents-block ub_table-of-contents\" id=\"ub_table-of-contents-7204bdcf-0451-4ec1-af86-cfeb2fb2016e\" data-linktodivider=\"false\" data-showtext=\"show\" data-hidetext=\"hide\" data-scrolltype=\"auto\" data-enablesmoothscroll=\"false\" data-initiallyhideonmobile=\"false\" data-initiallyshow=\"true\"><div class=\"ub_table-of-contents-header-container\" style=\"\">\n\t\t\t<div class=\"ub_table-of-contents-header\" style=\"text-align: left; \">\n\t\t\t\t<div class=\"ub_table-of-contents-title\">Contents:<\/div>\n\t\t\t\t\n\t\t\t<\/div>\n\t\t<\/div><div class=\"ub_table-of-contents-extra-container\" style=\"\">\n\t\t\t<div class=\"ub_table-of-contents-container ub_table-of-contents-1-column \">\n\t\t\t\t<ul style=\"\"><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#0-solution-1-brute-force-recursion\" style=\"\">Solution 1: Brute Force (Recursion)<\/a><ul><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#1-intuition\" style=\"\">Intuition<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#2-approach\" style=\"\">Approach<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#3-code\" style=\"\">Code<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#4-code-explanation\" style=\"\">Code Explanation<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#5-time-and-space-complexity\" style=\"\">Time and Space Complexity<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#6-simplified\" style=\"\">Simplified<\/a><\/li><\/ul><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#7-solution-2-memoization-top-down-dp\" style=\"\">Solution 2: Memoization (Top-Down DP)<\/a><ul><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#8-intuition\" style=\"\">Intuition<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#9-approach\" style=\"\">Approach<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#10-code\" style=\"\">Code<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#11-code-explanation\" style=\"\">Code Explanation<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#12-time-and-space-complexity\" style=\"\">Time and Space Complexity<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#13-simplified\" style=\"\">Simplified<\/a><\/li><\/ul><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#14-solution-3-tabulation-bottom-up-dp\" style=\"\">Solution 3: Tabulation (Bottom-Up DP)<\/a><ul><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#15-intuition\" style=\"\">Intuition<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#16-approach\" style=\"\">Approach<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#17-code\" style=\"\">Code<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#18-code-explanation\" style=\"\">Code Explanation<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#19-dry-run-example\" style=\"\">Dry Run Example<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#20-time-and-space-complexity\" style=\"\">Time and Space Complexity<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#21-simplified\" style=\"\">Simplified<\/a><\/li><\/ul><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#22-solution-4-space-optimized-tabulation-optimal\" style=\"\">Solution 4: Space-Optimized Tabulation (Optimal)<\/a><ul><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#23-intuition\" style=\"\">Intuition<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#24-approach\" style=\"\">Approach<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#25-code\" style=\"\">Code<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#26-code-explanation\" style=\"\">Code Explanation<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#27-dry-run-example\" style=\"\">Dry Run Example<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#28-time-and-space-complexity\" style=\"\">Time and Space Complexity<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#29-simplified\" style=\"\">Simplified<\/a><\/li><\/ul><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#30-summary-table\" style=\"\">Summary Table<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/triangle\/#31-conclusion\" style=\"\">Conclusion<\/a><\/li><\/ul>\n\t\t\t<\/div>\n\t\t<\/div><\/div>\n\n\n<h1 class=\"wp-block-heading\" id=\"0-solution-1-brute-force-recursion\">Solution 1: Brute Force (Recursion)<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1-intuition\">Intuition<\/h2>\n\n\n\n<p>At every cell&nbsp;<code>(row, col)<\/code>, you have two choices:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Move\u00a0<strong>down<\/strong>\u00a0(to\u00a0<code>(row+1, col)<\/code>)<\/li>\n\n\n\n<li>Move\u00a0<strong>diagonal<\/strong>\u00a0(to\u00a0<code>(row+1, col+1)<\/code>)<br>Recursively try both, summing the cell value and picking the path with the minimum sum.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"2-approach\">Approach<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Base case:<\/strong>\u00a0If you\u2019re at the last row, simply return the triangle\u2019s value at that cell.<\/li>\n\n\n\n<li><strong>Recursive case:<\/strong>\u00a0Add current cell\u2019s value to the min sum of the two options below.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3-code\">Code<\/h2>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"class Solution:\n    def solve(self, row, col, triangle):\n        # Base: Last row reached, only option is to take value\n        if row == len(triangle) - 1:\n            return triangle[row][col]\n        # Option 1: Go down in the triangle\n        down = triangle[row][col] + self.solve(row + 1, col, triangle)\n        # Option 2: Go down-diagonal\n        diagonal = triangle[row][col] + self.solve(row + 1, col + 1, triangle)\n        # Return the minimum path sum\n        return min(down, diagonal)\n\n    def minimumTotal(self, triangle: List[List[int]]) -&gt; int:\n        # Start recursion from the top of triangle\n        return self.solve(0, 0, triangle)\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Solution<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">solve<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">self<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">row<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">col<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">triangle<\/span><span style=\"color: #D4D4D4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Base: Last row reached, only option is to take value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> row == <\/span><span style=\"color: #DCDCAA\">len<\/span><span style=\"color: #D4D4D4\">(triangle) - <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> triangle[row][col]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Option 1: Go down in the triangle<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        down = triangle[row][col] + <\/span><span style=\"color: #569CD6\">self<\/span><span style=\"color: #D4D4D4\">.solve(row + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, col, triangle)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Option 2: Go down-diagonal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        diagonal = triangle[row][col] + <\/span><span style=\"color: #569CD6\">self<\/span><span style=\"color: #D4D4D4\">.solve(row + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, col + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, triangle)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Return the minimum path sum<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">min<\/span><span style=\"color: #D4D4D4\">(down, diagonal)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">minimumTotal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">self<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">triangle<\/span><span style=\"color: #D4D4D4\">: List[List[<\/span><span style=\"color: #4EC9B0\">int<\/span><span style=\"color: #D4D4D4\">]]) -&gt; <\/span><span style=\"color: #4EC9B0\">int<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Start recursion from the top of triangle<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">self<\/span><span style=\"color: #D4D4D4\">.solve(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, triangle)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4-code-explanation\">Code Explanation<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Start at the top of the triangle.<\/li>\n\n\n\n<li>At each stage, recursively branch to both child positions (down\/down-diagonal).<\/li>\n\n\n\n<li>At the leaf row, just return the number itself.<\/li>\n\n\n\n<li>The recursion automatically tries every possible valid top-to-bottom path.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5-time-and-space-complexity\">Time and Space Complexity<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Time:<\/strong>\u00a0O(2^n) (exponential, since each cell can branch to two children)<\/li>\n\n\n\n<li><strong>Space:<\/strong>\u00a0O(n) (recursion stack depth, n = number of rows)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6-simplified\">Simplified<\/h2>\n\n\n\n<p>Simple, but tries all possible routes, quickly exponential for large triangles!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"7-solution-2-memoization-top-down-dp\">Solution 2: Memoization (Top-Down DP)<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"8-intuition\">Intuition<\/h2>\n\n\n\n<p>Many subpaths are recalculated repeatedly. Use a 2D DP table,&nbsp;<code>dp[row][col]<\/code>, to remember already computed minimums. Before recursion, check if the answer is cached!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"9-approach\">Approach<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create\u00a0<code>dp<\/code>\u00a0table, initialized to\u00a0<code>None<\/code>.<\/li>\n\n\n\n<li>Before recursing, check if\u00a0<code>dp[row][col]<\/code>\u00a0is set.<\/li>\n\n\n\n<li>Store and re-use computed results.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"10-code\">Code<\/h2>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"class Solution:\n    def solve(self, row, col, triangle, dp):\n        # Base: last row\n        if row == len(triangle) - 1:\n            return triangle[row][col]\n        # Check if already computed\n        if dp[row][col] is not None:\n            return dp[row][col]\n        # Recursively find minimum for down and diagonal\n        down = triangle[row][col] + self.solve(row + 1, col, triangle, dp)\n        diagonal = triangle[row][col] + self.solve(row + 1, col + 1, triangle, dp)\n        dp[row][col] = min(down, diagonal)\n        return dp[row][col]\n\n    def minimumTotal(self, triangle: List[List[int]]) -&gt; int:\n        n = len(triangle)\n        # DP table same size as triangle, all None\n        dp = [[None] * n for _ in range(n)]\n        return self.solve(0, 0, triangle, dp)\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Solution<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">solve<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">self<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">row<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">col<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">triangle<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">dp<\/span><span style=\"color: #D4D4D4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Base: last row<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> row == <\/span><span style=\"color: #DCDCAA\">len<\/span><span style=\"color: #D4D4D4\">(triangle) - <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> triangle[row][col]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Check if already computed<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> dp[row][col] <\/span><span style=\"color: #569CD6\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">None<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> dp[row][col]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Recursively find minimum for down and diagonal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        down = triangle[row][col] + <\/span><span style=\"color: #569CD6\">self<\/span><span style=\"color: #D4D4D4\">.solve(row + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, col, triangle, dp)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        diagonal = triangle[row][col] + <\/span><span style=\"color: #569CD6\">self<\/span><span style=\"color: #D4D4D4\">.solve(row + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, col + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, triangle, dp)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        dp[row][col] = <\/span><span style=\"color: #DCDCAA\">min<\/span><span style=\"color: #D4D4D4\">(down, diagonal)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> dp[row][col]<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">minimumTotal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">self<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">triangle<\/span><span style=\"color: #D4D4D4\">: List[List[<\/span><span style=\"color: #4EC9B0\">int<\/span><span style=\"color: #D4D4D4\">]]) -&gt; <\/span><span style=\"color: #4EC9B0\">int<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        n = <\/span><span style=\"color: #DCDCAA\">len<\/span><span style=\"color: #D4D4D4\">(triangle)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># DP table same size as triangle, all None<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        dp = [[<\/span><span style=\"color: #569CD6\">None<\/span><span style=\"color: #D4D4D4\">] * n <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> _ <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(n)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">self<\/span><span style=\"color: #D4D4D4\">.solve(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, triangle, dp)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"11-code-explanation\">Code Explanation<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Adds a memoization table, so each (row, col) is evaluated once.<\/li>\n\n\n\n<li>If path sum from current cell is already solved, return it instantly.<\/li>\n\n\n\n<li>Converts exponential to polynomial time.<\/li>\n\n\n\n<li><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"12-time-and-space-complexity\">Time and Space Complexity<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Time:<\/strong>\u00a0O(n\u00b2) (every cell solved only once)<\/li>\n\n\n\n<li><strong>Space:<\/strong>\u00a0O(n\u00b2) for dp + O(n) stack<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"13-simplified\">Simplified<\/h2>\n\n\n\n<p>The &#8220;ACE&#8221; DP method for triangle: fast, clear, no repeats.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"14-solution-3-tabulation-bottom-up-dp\">Solution 3: Tabulation (Bottom-Up DP)<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"15-intuition\">Intuition<\/h2>\n\n\n\n<p>DP bottom-up: minimum path to reach each cell, starting from the last row (just its own values). Every upper cell is the cell value + the min of its two children (directly below and diagonal right).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"16-approach\">Approach<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>dp[i][j]<\/code>\u00a0means: min path starting at (i,j) down to base.<\/li>\n\n\n\n<li>Start: Fill last row.<\/li>\n\n\n\n<li>Move upwards, at each cell:<br><code>dp[i][j] = triangle[i][j] + min(dp[i+1][j], dp[i+1][j+1])<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"17-code\">Code<\/h2>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"class Solution:\n    def minimumTotal(self, triangle: List[List[int]]) -&gt; int:\n        n = len(triangle)\n        # Initiate DP grid, filled with None\n        dp = [[None] * n for _ in range(n)]\n        # Bottom row: path sum is value itself\n        for j in range(n):\n            dp[n - 1][j] = triangle[n - 1][j]\n        # Build up from second-last row to top\n        for i in range(n - 2, -1, -1):\n            for j in range(i + 1):\n                # Option 1: Down\n                down = triangle[i][j] + dp[i + 1][j]\n                # Option 2: Down-diagonal\n                diagonal = triangle[i][j] + dp[i + 1][j + 1]\n                dp[i][j] = min(down, diagonal)\n        return dp[0][0]\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Solution<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">minimumTotal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">self<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">triangle<\/span><span style=\"color: #D4D4D4\">: List[List[<\/span><span style=\"color: #4EC9B0\">int<\/span><span style=\"color: #D4D4D4\">]]) -&gt; <\/span><span style=\"color: #4EC9B0\">int<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        n = <\/span><span style=\"color: #DCDCAA\">len<\/span><span style=\"color: #D4D4D4\">(triangle)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Initiate DP grid, filled with None<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        dp = [[<\/span><span style=\"color: #569CD6\">None<\/span><span style=\"color: #D4D4D4\">] * n <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> _ <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(n)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Bottom row: path sum is value itself<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> j <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(n):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            dp[n - <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">][j] = triangle[n - <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">][j]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Build up from second-last row to top<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> i <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(n - <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">, -<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, -<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> j <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(i + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #6A9955\"># Option 1: Down<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                down = triangle[i][j] + dp[i + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">][j]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #6A9955\"># Option 2: Down-diagonal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                diagonal = triangle[i][j] + dp[i + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">][j + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                dp[i][j] = <\/span><span style=\"color: #DCDCAA\">min<\/span><span style=\"color: #D4D4D4\">(down, diagonal)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> dp[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">][<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">]<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"18-code-explanation\">Code Explanation<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fills from the bottom row upward.<\/li>\n\n\n\n<li>At every (i,j), you only need its two children (<code>j<\/code>,\u00a0<code>j+1<\/code>) on the row below.<\/li>\n\n\n\n<li>Result: dp stores the minimum path from top.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"19-dry-run-example\">Dry Run Example<\/h2>\n\n\n\n<p>With the same triangle:<br>Bottom-up, every cell gets its best min path, for the whole triangle.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"20-time-and-space-complexity\">Time and Space Complexity<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Time:<\/strong>\u00a0O(n\u00b2) (every cell filled once)<\/li>\n\n\n\n<li><strong>Space:<\/strong>\u00a0O(n\u00b2) (explicit DP table)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"21-simplified\">Simplified<\/h2>\n\n\n\n<p>Traditional DP synthesis for triangle, very easy to trace. Efficient for interview use.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"22-solution-4-space-optimized-tabulation-optimal\">Solution 4: Space-Optimized Tabulation (Optimal)<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"23-intuition\">Intuition<\/h2>\n\n\n\n<p>Each row only needs the DP values from the row below. Use two 1D arrays (<code>prev<\/code>&nbsp;and&nbsp;<code>curr<\/code>), switching as you move up the triangle.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"24-approach\">Approach<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Initiate 1D\u00a0<code>prev<\/code>\u00a0array as the last row of triangle.<\/li>\n\n\n\n<li>For each upper row, make a new\u00a0<code>curr<\/code>\u00a0array of its length.<\/li>\n\n\n\n<li>For each cell, calculate min path using\u00a0<code>prev[j]<\/code>\u00a0and\u00a0<code>prev[j+1]<\/code>.<\/li>\n\n\n\n<li>At end of each row, set\u00a0<code>prev = curr<\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"25-code\">Code<\/h2>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"class Solution:\n    def minimumTotal(self, triangle: List[List[int]]) -&gt; int:\n        n = len(triangle)\n        # Last row forms the initial DP array\n        prev = [-1] * n\n        for j in range(n):\n            prev[j] = triangle[n - 1][j]\n        # Move upwards from second-last row\n        for i in range(n - 2, -1, -1):\n            curr = [-1] * (i + 1)\n            for j in range(i + 1):\n                # Minimum path sum for current cell\n                down = triangle[i][j] + prev[j]\n                diagonal = triangle[i][j] + prev[j + 1]\n                curr[j] = min(down, diagonal)\n            prev = curr  # Update prev to current for next iteration\n        return prev[0]\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Solution<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">minimumTotal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">self<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">triangle<\/span><span style=\"color: #D4D4D4\">: List[List[<\/span><span style=\"color: #4EC9B0\">int<\/span><span style=\"color: #D4D4D4\">]]) -&gt; <\/span><span style=\"color: #4EC9B0\">int<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        n = <\/span><span style=\"color: #DCDCAA\">len<\/span><span style=\"color: #D4D4D4\">(triangle)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Last row forms the initial DP array<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        prev = [-<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] * n<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> j <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(n):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            prev[j] = triangle[n - <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">][j]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Move upwards from second-last row<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> i <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(n - <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">, -<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, -<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            curr = [-<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] * (i + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> j <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(i + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #6A9955\"># Minimum path sum for current cell<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                down = triangle[i][j] + prev[j]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                diagonal = triangle[i][j] + prev[j + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                curr[j] = <\/span><span style=\"color: #DCDCAA\">min<\/span><span style=\"color: #D4D4D4\">(down, diagonal)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            prev = curr  <\/span><span style=\"color: #6A9955\"># Update prev to current for next iteration<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> prev[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">]<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"26-code-explanation\">Code Explanation<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Only memory for two rows at a time.<\/li>\n\n\n\n<li>Seamlessly reduces O(n\u00b2) space to O(n).<\/li>\n\n\n\n<li>At the top,\u00a0<code>prev<\/code>\u00a0gives the answer.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"27-dry-run-example\">Dry Run Example<\/h2>\n\n\n\n<p>Same triangle; at each step up, fill out the best in a 1D rolling array.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"28-time-and-space-complexity\">Time and Space Complexity<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Time:<\/strong>\u00a0O(n\u00b2)<\/li>\n\n\n\n<li><strong>Space:<\/strong>\u00a0O(n) (just two rows at any time)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"29-simplified\">Simplified<\/h2>\n\n\n\n<p>Perfect for coding rounds with space constraints!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"30-summary-table\">Summary Table<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Approach<\/th><th>Time<\/th><th>Space<\/th><th>Best Use<\/th><\/tr><\/thead><tbody><tr><td>Recursion (Brute Force)<\/td><td>O(2^n)<\/td><td>O(n)<\/td><td>Learning, tiny triangles<\/td><\/tr><tr><td>Memoization (Top-Down DP)<\/td><td>O(n\u00b2)<\/td><td>O(n\u00b2)<\/td><td>Coding rounds, clarity<\/td><\/tr><tr><td>Tabulation (Bottom-Up DP)<\/td><td>O(n\u00b2)<\/td><td>O(n\u00b2)<\/td><td>Systematic, easy to debug<\/td><\/tr><tr><td>Space-Optimized Tabulation<\/td><td>O(n\u00b2)<\/td><td>O(n)<\/td><td>Production\/interview<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"31-conclusion\">Conclusion<\/h1>\n\n\n\n<p>The Triangle Minimum Path Sum problem is a classic on LeetCode and a beautiful showcase for dynamic programming. If you\u2019re new, start with recursion to build intuition. Move to memoization and iterative tabulation for true efficiency, and finish with space optimization for slick, real-world-ready code. Keep practicing DP for your next big interview!<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-16018d1d wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/codeanddebug.in\/course\/zero-to-hero-python-dsa\" target=\"_blank\" rel=\"noreferrer noopener\">Join our Advance DSA COURSE<\/a><\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><em>For any changes to the article, kindly email at <a href=\"mailto:code@codeanddebug.in\" target=\"_blank\" rel=\"noreferrer noopener\">code@codeanddebug.in<\/a> or contact us at <a href=\"tel:+91-9712928220\" target=\"_blank\" rel=\"noreferrer noopener\">+91-9712928220<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Given a&nbsp;triangle&nbsp;array, return&nbsp;the minimum path sum from top to bottom. For each step, you may move to an adjacent number of the row below. More formally, if you are on index&nbsp;i&nbsp;on the current row, you may move to either index&nbsp;i&nbsp;or index&nbsp;i + 1&nbsp;on the next row. Here&#8217;s the [Problem Link] to begin with. Example 1:<\/p>\n","protected":false},"author":1,"featured_media":834,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,6],"tags":[38,19],"class_list":{"0":"post-832","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-data-structures-and-algorithm","8":"category-intermediate","9":"tag-dynamic-programming-on-2d-arrays","10":"tag-medium"},"featured_image_src":"https:\/\/codeanddebug.in\/blog\/wp-content\/uploads\/2025\/08\/triangle-featured-image.png","author_info":{"display_name":"codeanddebug","author_link":"https:\/\/codeanddebug.in\/blog\/author\/codeanddebug\/"},"_links":{"self":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts\/832","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/comments?post=832"}],"version-history":[{"count":1,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts\/832\/revisions"}],"predecessor-version":[{"id":835,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts\/832\/revisions\/835"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/media\/834"}],"wp:attachment":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/media?parent=832"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/categories?post=832"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/tags?post=832"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}