From b4780b0d0f44e6ec3c84a355eeefa1f4b0048f02 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 21 Nov 2025 04:26:31 -0600 Subject: [PATCH] adding algo --- .../common_algos/two_sum_round_13.py | 16 +++ .../common_algos/valid_palindrome_round_13.py | 23 ++++ .../round_4/k_free_subsets.py | 111 ++++++++++++++++++ ...kids_with_the_greates_number_of_candies.py | 10 ++ .../number_of_1_bits.py | 6 + .../test_number_of_1_bits_round_21.py | 11 ++ 6 files changed, 177 insertions(+) create mode 100644 src/my_project/interviews/amazon_high_frequency_23/common_algos/two_sum_round_13.py create mode 100644 src/my_project/interviews/amazon_high_frequency_23/common_algos/valid_palindrome_round_13.py create mode 100644 src/my_project/interviews/amazon_high_frequency_23/round_4/k_free_subsets.py create mode 100644 src/my_project/interviews/amazon_high_frequency_23/round_4/kids_with_the_greates_number_of_candies.py create mode 100644 src/my_project/interviews/top_150_questions_round_21/number_of_1_bits.py create mode 100644 tests/test_150_questions_round_21/test_number_of_1_bits_round_21.py diff --git a/src/my_project/interviews/amazon_high_frequency_23/common_algos/two_sum_round_13.py b/src/my_project/interviews/amazon_high_frequency_23/common_algos/two_sum_round_13.py new file mode 100644 index 00000000..6c0c6330 --- /dev/null +++ b/src/my_project/interviews/amazon_high_frequency_23/common_algos/two_sum_round_13.py @@ -0,0 +1,16 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + + answer = dict() + + for k, v in enumerate(nums): + + if v in answer: + return [answer[v], k] + else: + answer[target - v] = k + + return [] \ No newline at end of file diff --git a/src/my_project/interviews/amazon_high_frequency_23/common_algos/valid_palindrome_round_13.py b/src/my_project/interviews/amazon_high_frequency_23/common_algos/valid_palindrome_round_13.py new file mode 100644 index 00000000..82f08a6e --- /dev/null +++ b/src/my_project/interviews/amazon_high_frequency_23/common_algos/valid_palindrome_round_13.py @@ -0,0 +1,23 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod +import re + +class Solution: + def isPalindrome(self, s: str) -> bool: + + # To lowercase + s = s.lower() + + # Remove non-alphanumeric characters + s = re.sub(pattern=r'[^a-zA-Z0-9]', repl='', string=s) + + # Determine if s is palindrome or not + + len_s = len(s) + + for i in range(len_s//2): + + if s[i] != s[len_s - 1 - i]: + return False + + return True \ No newline at end of file diff --git a/src/my_project/interviews/amazon_high_frequency_23/round_4/k_free_subsets.py b/src/my_project/interviews/amazon_high_frequency_23/round_4/k_free_subsets.py new file mode 100644 index 00000000..09639612 --- /dev/null +++ b/src/my_project/interviews/amazon_high_frequency_23/round_4/k_free_subsets.py @@ -0,0 +1,111 @@ +from typing import List, Union, Collection, Mapping, Optional +from collections import defaultdict + +class Solution: + def countTheNumOfKFreeSubsets(self, nums: List[int], k: int) -> int: + """ + Count k-Free subsets using dynamic programming. + + Approach: + 1. Group elements by (num % k) to find independent groups + 2. Within each group, sort and build chains where elements differ by k + 3. For each chain, use House Robber DP to count valid subsets + 4. Multiply results across all independent chains + + Time: O(n log n), Space: O(n) + """ + # Group numbers by their remainder when divided by k + groups = defaultdict(list) + for num in nums: + groups[num % k].append(num) + + res = 1 + + # Process each group independently + for group in groups.values(): + group.sort() + + # Build chains within this group + i = 0 + while i < len(group): + chain = [group[i]] + j = i + 1 + + # Build chain where each element is exactly k more than previous + while j < len(group) and group[j] == chain[-1] + k: + chain.append(group[j]) + j += 1 + + # House Robber DP for this chain + m = len(chain) + if m == 1: + chain_res = 2 # {} or {chain[0]} + else: + take = 1 # Take first element + skip = 1 # Skip first element + + for idx in range(1, m): + new_take = skip # Can only take current if we skipped previous + new_skip = take + skip # Can skip current regardless + take, skip = new_take, new_skip + + chain_res = take + skip + + res *= chain_res + i = j + + return res + + + + + +''' +Detailed Algorithm Explanation +Part 1: Why Group by num % k? +Two numbers can have a difference of exactly k only if they have the same remainder when divided by k. + +Mathematical proof: + +If a - b = k, then a = b + k +Therefore: a % k = (b + k) % k = b % k +Example: nums = [2, 3, 5, 8], k = 5 + +num | num % 5 | group +----|---------|------- +2 | 2 | Group A +3 | 3 | Group B +5 | 0 | Group C +8 | 3 | Group B + + +Why this matters: Elements from different groups can never differ by k, so they're independent. We can combine any subset from Group A with any subset from Group B. + +Part 2: Building Chains +Within each group, we sort and find chains where consecutive elements differ by exactly k. + +Example with Group B: [3, 8] + +Sorted: [3, 8] +Check: 8 - 3 = 5 ✓ +Chain: 3 → 8 + +Another example: nums = [1, 6, 11, 21], k = 5 (all have remainder 1) + +Sorted: [1, 6, 11, 21] +Check: 6-1=5 ✓, 11-6=5 ✓, 21-11=10 ✗ +Chains: [1 → 6 → 11], [21] + + +Part 3: House Robber DP - The Core Logic +For a chain like [3 → 8], we can't pick both 3 and 8 (they differ by k). This is the House Robber problem: count all subsets where we don't pick adjacent elements. + +DP State Variables +take = number of valid subsets that INCLUDE the current element +skip = number of valid subsets that EXCLUDE the current element + +DP Transitions +new_take = skip # To take current, we MUST have skipped previous +new_skip = take + skip # To skip current, we can take or skip previous + +''' \ No newline at end of file diff --git a/src/my_project/interviews/amazon_high_frequency_23/round_4/kids_with_the_greates_number_of_candies.py b/src/my_project/interviews/amazon_high_frequency_23/round_4/kids_with_the_greates_number_of_candies.py new file mode 100644 index 00000000..7b62f40e --- /dev/null +++ b/src/my_project/interviews/amazon_high_frequency_23/round_4/kids_with_the_greates_number_of_candies.py @@ -0,0 +1,10 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class Solution: + def kidsWithCandies(self, candies: List[int], extraCandies: int) -> List[bool]: + max_candies = max(candies) + return [candy + extraCandies >= max_candies for candy in candies] + + + diff --git a/src/my_project/interviews/top_150_questions_round_21/number_of_1_bits.py b/src/my_project/interviews/top_150_questions_round_21/number_of_1_bits.py new file mode 100644 index 00000000..eafdab14 --- /dev/null +++ b/src/my_project/interviews/top_150_questions_round_21/number_of_1_bits.py @@ -0,0 +1,6 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class Solution: + def hammingWeight(self, n: int) -> int: + return bin(n).count('1') diff --git a/tests/test_150_questions_round_21/test_number_of_1_bits_round_21.py b/tests/test_150_questions_round_21/test_number_of_1_bits_round_21.py new file mode 100644 index 00000000..f190e737 --- /dev/null +++ b/tests/test_150_questions_round_21/test_number_of_1_bits_round_21.py @@ -0,0 +1,11 @@ +import unittest +from src.my_project.interviews.top_150_questions_round_21\ +.number_of_1_bits import Solution + +class NumberOfOnesTestCase(unittest.TestCase): + + def test_number_of_ones(self): + solution = Solution() + output = solution.hammingWeight(n=11) + target = 3 + self.assertEqual(output, target) \ No newline at end of file