diff --git a/src/my_project/interviews/top_150_questions_round_22/ex_15_candy.py b/src/my_project/interviews/top_150_questions_round_22/ex_15_candy.py new file mode 100644 index 00000000..07a97460 --- /dev/null +++ b/src/my_project/interviews/top_150_questions_round_22/ex_15_candy.py @@ -0,0 +1,94 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class Solution: + def candy(self, ratings: List[int]) -> int: + """ + Distribute candies to children based on ratings. + + Rules: + 1. Each child gets at least 1 candy + 2. Children with higher rating than neighbors get more candies + + Strategy: Two-pass greedy + - Left-to-right: Ensure each child has more candies than left neighbor if rating is higher + - Right-to-left: Ensure each child has more candies than right neighbor if rating is higher + - Take maximum from both passes to satisfy both neighbors + + Time: O(n), Space: O(n) + """ + + n = len(ratings) + if n == 0: + return 0 + + # Initialize all children with 1 candy + candies = [1] * n + + # Left-to-right pass: Compare with left neighbor + # If current child has higher rating than left neighbor, + # give them one more candy than left neighbor + for i in range(1, n): + if ratings[i] > ratings[i - 1]: + candies[i] = candies[i - 1] + 1 + + # Right-to-left pass: Compare with right neighbor + # If current child has higher rating than right neighbor, + # ensure they have more candies (take max of current and right+1) + for i in range(n - 2, -1, -1): + if ratings[i] > ratings[i + 1]: + candies[i] = max(candies[i], candies[i + 1] + 1) + + # Return total candies needed + return sum(candies) + + +""" +Example walkthrough for ratings = [1, 0, 2]: + +Initial: candies = [1, 1, 1] + +Left-to-right pass: +i=1: ratings[1]=0 < ratings[0]=1 → no change → candies = [1, 1, 1] +i=2: ratings[2]=2 > ratings[1]=0 → candies[2] = candies[1] + 1 = 2 → candies = [1, 1, 2] + +Right-to-left pass: +i=1: ratings[1]=0 < ratings[2]=2 → no change → candies = [1, 1, 2] +i=0: ratings[0]=1 > ratings[1]=0 → candies[0] = max(1, 1+1) = 2 → candies = [2, 1, 2] + +Total: 2 + 1 + 2 = 5 + + +Example walkthrough for ratings = [1, 2, 2]: + +Initial: candies = [1, 1, 1] + +Left-to-right pass: +i=1: ratings[1]=2 > ratings[0]=1 → candies[1] = 1 + 1 = 2 → candies = [1, 2, 1] +i=2: ratings[2]=2 = ratings[1]=2 → no change → candies = [1, 2, 1] + +Right-to-left pass: +i=1: ratings[1]=2 = ratings[2]=2 → no change → candies = [1, 2, 1] +i=0: ratings[0]=1 < ratings[1]=2 → no change → candies = [1, 2, 1] + +Total: 1 + 2 + 1 = 4 + + +Example walkthrough for ratings = [1, 3, 2, 2, 1]: + +Initial: candies = [1, 1, 1, 1, 1] + +Left-to-right: +i=1: 3 > 1 → candies[1] = 2 → [1, 2, 1, 1, 1] +i=2: 2 < 3 → no change → [1, 2, 1, 1, 1] +i=3: 2 = 2 → no change → [1, 2, 1, 1, 1] +i=4: 1 < 2 → no change → [1, 2, 1, 1, 1] + +Right-to-left: +i=3: 2 > 1 → candies[3] = max(1, 2) = 2 → [1, 2, 1, 2, 1] +i=2: 2 = 2 → no change → [1, 2, 1, 2, 1] +i=1: 3 > 2 → candies[1] = max(2, 2) = 2 → [1, 2, 1, 2, 1] +i=0: 1 < 3 → no change → [1, 2, 1, 2, 1] + +Total: 1 + 2 + 1 + 2 + 1 = 7 +""" diff --git a/src/my_project/interviews/top_150_questions_round_22/ex_16_trapping_rain_water.py b/src/my_project/interviews/top_150_questions_round_22/ex_16_trapping_rain_water.py new file mode 100644 index 00000000..03530048 --- /dev/null +++ b/src/my_project/interviews/top_150_questions_round_22/ex_16_trapping_rain_water.py @@ -0,0 +1,45 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class Solution: + def trap(self, height: List[int]) -> int: + """ + Calculate how much water can be trapped after raining. + + Key insight: Water trapped at position i = min(max_left, max_right) - height[i] + (if positive) + + Strategy: Two-pointer approach + - Use two pointers from both ends + - Track max height seen from left and right + - Move pointer with smaller max height (water level determined by shorter side) + - Add water trapped at current position + + Time: O(n), Space: O(1) + """ + + if not height or len(height) < 3: + return 0 + + left, right = 0, len(height) - 1 + left_max, right_max = 0, 0 + water_trapped = 0 + + while left < right: + # Update max heights seen so far + left_max = max(left_max, height[left]) + right_max = max(right_max, height[right]) + + # Water level is determined by the shorter side + if left_max < right_max: + # Left side is shorter, so water trapped at left position + # is determined by left_max + water_trapped += left_max - height[left] + left += 1 + else: + # Right side is shorter or equal, so water trapped at right position + # is determined by right_max + water_trapped += right_max - height[right] + right -= 1 + + return water_trapped diff --git a/tests/test_150_questions_round_22/test_15_candy_round_22.py b/tests/test_150_questions_round_22/test_15_candy_round_22.py new file mode 100644 index 00000000..5be16774 --- /dev/null +++ b/tests/test_150_questions_round_22/test_15_candy_round_22.py @@ -0,0 +1,17 @@ +import unittest +from src.my_project.interviews.top_150_questions_round_22\ +.ex_15_candy import Solution + +class CandyTestCase(unittest.TestCase): + + def test_candy_first_case(self): + solution = Solution() + output = solution.candy(ratings = [1,0,2]) + target = 5 + self.assertEqual(output, target) + + def test_candy_second_case(self): + solution = Solution() + output = solution.candy(ratings = [1,2,2]) + target = 4 + self.assertEqual(output, target) \ No newline at end of file diff --git a/tests/test_150_questions_round_22/test_16_trapping_rain_water_round_22.py b/tests/test_150_questions_round_22/test_16_trapping_rain_water_round_22.py new file mode 100644 index 00000000..539ca243 --- /dev/null +++ b/tests/test_150_questions_round_22/test_16_trapping_rain_water_round_22.py @@ -0,0 +1,17 @@ +import unittest +from src.my_project.interviews.top_150_questions_round_22\ +.ex_16_trapping_rain_water import Solution + +class TrappingWaterTestCase(unittest.TestCase): + + def test_trapping_water_first_case(self): + solution = Solution() + output = solution.trap(height = [0,1,0,2,1,0,1,3,2,1,2,1]) + target = 6 + self.assertEqual(output, target) + + def test_trapping_water_second_case(self): + solution = Solution() + output = solution.trap(height = [4,2,0,3,2,5]) + target = 9 + self.assertEqual(output, target) \ No newline at end of file