From fbf3da5cdc49a377e88b457f7928c56251608478 Mon Sep 17 00:00:00 2001 From: ananya-research Date: Tue, 30 Sep 2025 21:01:51 -0400 Subject: [PATCH 1/4] Create triangle.py LeetCode ques 120, utilizing DP --- dynamic_programming/triangle.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 dynamic_programming/triangle.py diff --git a/dynamic_programming/triangle.py b/dynamic_programming/triangle.py new file mode 100644 index 000000000000..ef64a7585b4a --- /dev/null +++ b/dynamic_programming/triangle.py @@ -0,0 +1,11 @@ +class Solution: + def minimumTotal(self, triangle: List[List[int]]) -> int: + for row in range(1, len(triangle)): + for col in range(row + 1): + smallest_above = math.inf + if col > 0: + smallest_above = triangle[row - 1][col - 1] + if col < row: + smallest_above = min(smallest_above, triangle[row - 1][col]) + triangle[row][col] += smallest_above + return min(triangle[-1]) From e74bef62a55214ee7e3c1f28f2e318c29131164e Mon Sep 17 00:00:00 2001 From: ananya-research Date: Tue, 30 Sep 2025 21:08:59 -0400 Subject: [PATCH 2/4] Update triangle.py Updated the format --- dynamic_programming/triangle.py | 53 ++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/dynamic_programming/triangle.py b/dynamic_programming/triangle.py index ef64a7585b4a..55e3d80f7cfe 100644 --- a/dynamic_programming/triangle.py +++ b/dynamic_programming/triangle.py @@ -1,11 +1,42 @@ -class Solution: - def minimumTotal(self, triangle: List[List[int]]) -> int: - for row in range(1, len(triangle)): - for col in range(row + 1): - smallest_above = math.inf - if col > 0: - smallest_above = triangle[row - 1][col - 1] - if col < row: - smallest_above = min(smallest_above, triangle[row - 1][col]) - triangle[row][col] += smallest_above - return min(triangle[-1]) +from __future__ import annotations + + +def minimum_total(triangle: list[list[int]]) -> int: + """ + Return the minimum path sum from top to bottom of a triangle. + + Each step you may move to adjacent numbers on the row below. + The input must be a proper triangle: len(row i) == i + 1. + + >>> minimum_total([[2],[3,4],[6,5,7],[4,1,8,3]]) + 11 + >>> minimum_total([[-10]]) + -10 + >>> minimum_total([[1],[2,3]]) + 3 + >>> minimum_total([]) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ValueError: triangle must be non-empty and well-formed + >>> minimum_total([[1],[2]]) # malformed (second row length not 2) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ValueError: triangle must be non-empty and well-formed + """ + # Basic validation: non-empty and proper "triangle" shape + if not triangle or any(len(row) != i + 1 for i, row in enumerate(triangle)): + raise ValueError("triangle must be non-empty and well-formed") + + # Start from the last row and fold upwards. + # dp[j] will store the minimum path sum from row r to the bottom starting at column j. + dp = triangle[-1][:] # copy so we don't mutate the input + + for r in range(len(triangle) - 2, -1, -1): + for c in range(r + 1): + dp[c] = triangle[r][c] + min(dp[c], dp[c + 1]) + + return dp[0] + + +if __name__ == "__main__": + import doctest + + doctest.testmod() From 8f93961862f3dc1407944d4e7bb672ca853305b5 Mon Sep 17 00:00:00 2001 From: ananya-research Date: Tue, 30 Sep 2025 21:13:22 -0400 Subject: [PATCH 3/4] Update triangle.py --- dynamic_programming/triangle.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dynamic_programming/triangle.py b/dynamic_programming/triangle.py index 55e3d80f7cfe..9fdfc1f8d9cd 100644 --- a/dynamic_programming/triangle.py +++ b/dynamic_programming/triangle.py @@ -17,7 +17,7 @@ def minimum_total(triangle: list[list[int]]) -> int: >>> minimum_total([]) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ValueError: triangle must be non-empty and well-formed - >>> minimum_total([[1],[2]]) # malformed (second row length not 2) # doctest: +IGNORE_EXCEPTION_DETAIL + >>> minimum_total([[1],[2]]) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ValueError: triangle must be non-empty and well-formed """ @@ -25,8 +25,8 @@ def minimum_total(triangle: list[list[int]]) -> int: if not triangle or any(len(row) != i + 1 for i, row in enumerate(triangle)): raise ValueError("triangle must be non-empty and well-formed") - # Start from the last row and fold upwards. - # dp[j] will store the minimum path sum from row r to the bottom starting at column j. + # Start from the last row and fold upwards. dp[j] stores the minimum path + # sum from row r to the bottom starting at column j. dp = triangle[-1][:] # copy so we don't mutate the input for r in range(len(triangle) - 2, -1, -1): From bf63913303956a2d82ada4852d4249881e4cf201 Mon Sep 17 00:00:00 2001 From: ananya-research Date: Wed, 1 Oct 2025 15:22:12 +1400 Subject: [PATCH 4/4] Create design_hit_counter.py LC 362 --- data_structures/queues/design_hit_counter.py | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 data_structures/queues/design_hit_counter.py diff --git a/data_structures/queues/design_hit_counter.py b/data_structures/queues/design_hit_counter.py new file mode 100644 index 000000000000..b72dc11176fa --- /dev/null +++ b/data_structures/queues/design_hit_counter.py @@ -0,0 +1,39 @@ +from collections import deque + + +class HitCounter: + """ + A counter that records hits (events) and can return + the number of hits in the past 5 minutes (300 seconds). + + >>> hc = HitCounter() + >>> hc.hit(1) + >>> hc.hit(2) + >>> hc.hit(300) + >>> hc.get_hits(300) + 3 + >>> hc.get_hits(301) + 2 + """ + + def __init__(self) -> None: + self.hits: deque[int] = deque() + + def hit(self, timestamp: int) -> None: + """Record a hit at the given timestamp (in seconds).""" + self.hits.append(timestamp) + + def get_hits(self, timestamp: int) -> int: + """ + Return the number of hits in the past 5 minutes + from the given timestamp. + """ + while self.hits and self.hits[0] <= timestamp - 300: + self.hits.popleft() + return len(self.hits) + + +if __name__ == "__main__": + import doctest + + doctest.testmod()