<p>Given a <code>triangle</code> array, return <em>the minimum path sum from top to bottom</em>.</p>

<p>For each step, you may move to an adjacent number of the row below. More formally, if you are on index <code>i</code> on the current row, you may move to either index <code>i</code> or index <code>i + 1</code> on the next row.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
<strong>Output:</strong> 11
<strong>Explanation:</strong> The triangle looks like:
   <u>2</u>
  <u>3</u> 4
 6 <u>5</u> 7
4 <u>1</u> 8 3
The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> triangle = [[-10]]
<strong>Output:</strong> -10
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= triangle.length &lt;= 200</code></li>
	<li><code>triangle[0].length == 1</code></li>
	<li><code>triangle[i].length == triangle[i - 1].length + 1</code></li>
	<li><code>-10<sup>4</sup> &lt;= triangle[i][j] &lt;= 10<sup>4</sup></code></li>
</ul>

<p>&nbsp;</p>
<strong>Follow up:</strong> Could you&nbsp;do this using only <code>O(n)</code> extra space, where <code>n</code> is the total number of rows in the triangle?
class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:

        # NOTE: 
        # By starting from the top, we have implemented a greedy approach through the selection of 2 adjacent numbers in the next row
        # However, the minimum path might require choosing a non-greedy step at an earlier stage.
        # we should use dynamic programming, starting from the bottom of the triangle


        length = len(triangle)

        min_sum = 0

        # start from the second last row and move up
        # range(start_index, stop_index - up to but not including, step)
        for row in range(length-2, -1, -1):
            
            length_row = len(triangle[row])
            
            for index in range(length_row):
                min_sum = min(triangle[row+1][index], triangle[row+1][index+1])

                # replace current with the min sum
                current = triangle[row][index]
                triangle[row][index] = min_sum + current

        return triangle[0][0]

        # length = len(triangle)

        # dp = [0] * length

        # dp[0] = triangle[0][0]

        # i = 0

        # for row in range(1, length):
        #     # get the index of the number to select on next row
        #     if triangle[row][i] <= triangle[row][i+1]:
        #         # i stay the same
        #         dp[row] = dp[row-1] + triangle[row][i]
        #         print("i stay same: ", i)
        #     else:
        #         dp[row] = dp[row-1] + triangle[row][i+1]
        #         i = i + 1
        #         print("i +1 : ", i)

        # return dp[-1]


        

         
17800