From cb9bc3c3865dc0f779c836aaac90e7ad80ae0b85 Mon Sep 17 00:00:00 2001 From: Sanket Kale Date: Sun, 21 Jun 2026 10:45:55 -0500 Subject: [PATCH] Completed DP-3 --- Problem1.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ Problem2.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 Problem1.py create mode 100644 Problem2.py diff --git a/Problem1.py b/Problem1.py new file mode 100644 index 00000000..3c64a985 --- /dev/null +++ b/Problem1.py @@ -0,0 +1,45 @@ +## Problem1: (https://leetcode.com/problems/delete-and-earn/) +class Solution: + def deleteAndEarn(self, nums: List[int]) -> int: + """ + Calculates the maximum points you can earn by deleting elements. + + Time Complexity: O(N + M) + - N is the number of elements in `nums`. + - M is the maximum value in `nums`. + Finding the max takes O(N). Initializing and iterating through the + `sumOfFreq` array takes O(M). Populating it takes O(N). + Total Time = O(N) + O(M) + O(N) + O(M) = O(N + M). + + Space Complexity: O(M) + - We create an array `sumOfFreq` of size M + 1. + - The DP variables (previous, current, temp) only use O(1) space. + Total Space = O(M). + """ + # Time: O(N) to find the maximum element + maxInArr = max(nums) + + # Space: O(M) for an array of size maxInArr + 1 + # Time: O(M) to initialize + sumOfFreq = [0 for _ in range(maxInArr + 1)] + + # Time: O(N) to iterate through nums and populate the frequency sum + for n in nums: + sumOfFreq[n] += n + + n = len(sumOfFreq) + + if n == 2: + return sumOfFreq[1] + + previous = sumOfFreq[0] + current = max(previous, sumOfFreq[1]) + + # Time: O(M) to iterate through the sumOfFreq array + for i in range(2, n): + # Space: O(1) for temporary variables + temp = max(current, sumOfFreq[i] + previous) + previous = current + current = temp + + return current \ No newline at end of file diff --git a/Problem2.py b/Problem2.py new file mode 100644 index 00000000..f964df3b --- /dev/null +++ b/Problem2.py @@ -0,0 +1,33 @@ +## Problem2 (https://leetcode.com/problems/minimum-falling-path-sum/) +class Solution: + def minFallingPathSum(self, matrix: List[List[int]]) -> int: + """ + Time Complexity: O(N^2), where N is the number of rows (and columns) in the matrix. + We iterate through almost every cell in the NxN matrix exactly once. + Space Complexity: O(1) auxiliary space. We modify the input matrix in-place to store + our intermediate results, so no extra proportional memory is allocated. + """ + rows = len(matrix) + + # We start from the second row (index 1) because the minimum falling path sum + # to reach any cell in the first row is just the value of the cell itself. + for r in range(1, rows): + for c in range(rows): + + # Fetch the three possible paths from the row directly above: + # 1. Left diagonal (check bounds to ensure we don't wrap around) + left = matrix[r - 1][c - 1] if c > 0 else float('inf') + + # 2. Directly above + mid = matrix[r - 1][c] + + # 3. Right diagonal (check bounds) + right = matrix[r - 1][c + 1] if c < rows - 1 else float('inf') + + # Update the current cell to store the minimum sum required to reach it. + # This builds our optimal substructure moving downwards. + matrix[r][c] = matrix[r][c] + min(left, mid, right) + + # After processing all rows, the last row contains the minimum path sums + # ending at each respective column. The answer is simply the smallest one. + return min(matrix[-1]) \ No newline at end of file