Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions Problem1.py
Original file line number Diff line number Diff line change
@@ -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
33 changes: 33 additions & 0 deletions Problem2.py
Original file line number Diff line number Diff line change
@@ -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])