From 5fdc2e5a4d4487d2c2159ecc95568c9d4fd206ba Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 4 Dec 2025 04:28:32 -0600 Subject: [PATCH] adding algo --- .../ex_13_product_of_array_except_itself.py | 36 +++++++++++++++ .../ex_14_gas_station.py | 45 +++++++++++++++++++ ...product_of_array_except_itself_round_22.py | 17 +++++++ .../test_14_gas_station_round_22.py | 18 ++++++++ 4 files changed, 116 insertions(+) create mode 100644 src/my_project/interviews/top_150_questions_round_22/ex_13_product_of_array_except_itself.py create mode 100644 src/my_project/interviews/top_150_questions_round_22/ex_14_gas_station.py create mode 100644 tests/test_150_questions_round_22/test_13_product_of_array_except_itself_round_22.py create mode 100644 tests/test_150_questions_round_22/test_14_gas_station_round_22.py diff --git a/src/my_project/interviews/top_150_questions_round_22/ex_13_product_of_array_except_itself.py b/src/my_project/interviews/top_150_questions_round_22/ex_13_product_of_array_except_itself.py new file mode 100644 index 00000000..85d984ed --- /dev/null +++ b/src/my_project/interviews/top_150_questions_round_22/ex_13_product_of_array_except_itself.py @@ -0,0 +1,36 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class Solution: + def productExceptSelf(self, nums: List[int]) -> List[int]: + """ + Calculate product of all elements except self without division. + + Strategy: Two-pass with prefix and suffix products + - First pass: Build prefix products (product of all elements to the left) + - Second pass: Build suffix products (product of all elements to the right) + - Result[i] = prefix[i] * suffix[i] + + Optimization: Use output array to store prefix, then multiply by suffix in-place + + Time: O(n), Space: O(1) excluding output array + """ + + n = len(nums) + answer = [1] * n + + # First pass: Calculate prefix products + # answer[i] contains product of all elements to the left of i + prefix = 1 + for i in range(n): + answer[i] = prefix + prefix *= nums[i] + + # Second pass: Calculate suffix products and multiply with prefix + # For each position, multiply existing prefix with product of all elements to the right + suffix = 1 + for i in range(n - 1, -1, -1): + answer[i] *= suffix + suffix *= nums[i] + + return answer \ No newline at end of file diff --git a/src/my_project/interviews/top_150_questions_round_22/ex_14_gas_station.py b/src/my_project/interviews/top_150_questions_round_22/ex_14_gas_station.py new file mode 100644 index 00000000..376c7768 --- /dev/null +++ b/src/my_project/interviews/top_150_questions_round_22/ex_14_gas_station.py @@ -0,0 +1,45 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class Solution: + def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int: + """ + Find the starting gas station to complete the circuit. + + Key insights: + 1. If total gas < total cost, impossible to complete circuit + 2. If we can't reach station j from station i, then we can't reach j + from any station between i and j (they all have negative tank balance) + 3. If a solution exists, it's guaranteed to be unique + + Strategy: Greedy one-pass + - Track total gas surplus/deficit + - Track current tank from potential starting point + - If tank goes negative, reset start to next station + + Time: O(n), Space: O(1) + """ + + n = len(gas) + total_gas = 0 # Total gas surplus/deficit for entire circuit + current_tank = 0 # Current gas in tank from start_station + start_station = 0 # Potential starting station + + for i in range(n): + # Calculate net gas at this station (gain - cost to next) + net_gas = gas[i] - cost[i] + + # Add to both total and current tank + total_gas += net_gas + current_tank += net_gas + + # If current tank is negative, we can't reach next station from start_station + # All stations from start_station to i are invalid starting points + # Try starting from the next station (i + 1) + if current_tank < 0: + start_station = i + 1 # Reset starting point + current_tank = 0 # Reset tank + + # If total gas is negative, impossible to complete circuit + # Otherwise, start_station is the answer + return start_station if total_gas >= 0 else -1 \ No newline at end of file diff --git a/tests/test_150_questions_round_22/test_13_product_of_array_except_itself_round_22.py b/tests/test_150_questions_round_22/test_13_product_of_array_except_itself_round_22.py new file mode 100644 index 00000000..95b181ce --- /dev/null +++ b/tests/test_150_questions_round_22/test_13_product_of_array_except_itself_round_22.py @@ -0,0 +1,17 @@ +import unittest +from src.my_project.interviews.top_150_questions_round_22\ +.ex_13_product_of_array_except_itself import Solution + +class ProductExcetItselfTestCase(unittest.TestCase): + + def test_product_first_case(self): + solution = Solution() + output = solution.productExceptSelf(nums = [1,2,3,4]) + target = [24,12,8,6] + self.assertEqual(output, target) + + def test_product_second_case(self): + solution = Solution() + output = solution.productExceptSelf(nums = [-1,1,0,-3,3]) + target = [0,0,9,0,0] + self.assertEqual(output, target) \ No newline at end of file diff --git a/tests/test_150_questions_round_22/test_14_gas_station_round_22.py b/tests/test_150_questions_round_22/test_14_gas_station_round_22.py new file mode 100644 index 00000000..c1b288c3 --- /dev/null +++ b/tests/test_150_questions_round_22/test_14_gas_station_round_22.py @@ -0,0 +1,18 @@ +import unittest +from src.my_project.interviews.top_150_questions_round_22\ +.ex_14_gas_station import Solution + +class GasStationTestCase(unittest.TestCase): + + def test_gas_station_first_case(self): + solution = Solution() + output = solution.canCompleteCircuit(gas = [1,2,3,4,5], + cost = [3,4,5,1,2]) + target = 3 + self.assertEqual(output, target) + + def test_gas_station_second_case(self): + solution = Solution() + output = solution.canCompleteCircuit(gas = [2,3,4], cost = [3,4,3]) + target = -1 + self.assertEqual(output, target) \ No newline at end of file