diff --git a/DIRECTORY.md b/DIRECTORY.md index c79ace86..bef1f660 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -23,6 +23,8 @@ * [Test Is Valid Subsequence](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/arrays/subsequence/test_is_valid_subsequence.py) * Two Sum * [Test Two Sum](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/arrays/two_sum/test_two_sum.py) + * Two Sum Less K + * [Test Two Sum](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/arrays/two_sum_less_k/test_two_sum.py) * Backtracking * Combination * [Test Combination 2](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/backtracking/combination/test_combination_2.py) diff --git a/algorithms/arrays/two_sum/__init__.py b/algorithms/arrays/two_sum/__init__.py index 61a7a8e7..6b79adc2 100644 --- a/algorithms/arrays/two_sum/__init__.py +++ b/algorithms/arrays/two_sum/__init__.py @@ -27,6 +27,7 @@ def two_sum(numbers: List[int], target: int) -> List[int]: if complement in m: return [m[complement], idx] m[num] = idx + return [] def two_sum_with_pointers(numbers: List[int], target: int) -> List[int]: diff --git a/algorithms/arrays/two_sum_less_k/README.md b/algorithms/arrays/two_sum_less_k/README.md new file mode 100644 index 00000000..cdefe60f --- /dev/null +++ b/algorithms/arrays/two_sum_less_k/README.md @@ -0,0 +1,23 @@ +# Two Sum Less Than K + +Given an array of integers, nums, and an integer k, find the maximum sum of two elements in nums less than k. Otherwise, +return −1 if no such pair exists. + +Constraints + +- 1 ≤ nums.length ≤ 100 +- 1 ≤ nums[i] ≤ 10^3 +- 1 ≤ k ≤ 10^3 + +## Examples + +![Example 1](./images/examples/two_sum_less_k_example_1.png) +![Example 2](./images/examples/two_sum_less_k_example_2.png) +![Example 3](./images/examples/two_sum_less_k_example_3.png) +![Example 4](./images/examples/two_sum_less_k_example_4.png) + +## Related Topics + +- Array +- Two Pointers +- Binary Search diff --git a/algorithms/arrays/two_sum_less_k/__init__.py b/algorithms/arrays/two_sum_less_k/__init__.py new file mode 100644 index 00000000..86dff9a3 --- /dev/null +++ b/algorithms/arrays/two_sum_less_k/__init__.py @@ -0,0 +1,56 @@ +from typing import List + + +def two_sum_less_than_k(nums: List[int], k: int) -> int: + """ + Finds the maximum sum of two elements in a given list of numbers that is less than k. + Uses binary search to achieve a time complexity of O(n log n) and find the maximum sum of two elements + that is less than k. It takes the nums array and the target value k as input. + Args: + nums (List[int]): A sorted list of integers + k int: The target value to search for + Returns: + The maximum sum of two elements that is less than k + """ + max_sum = -1 + + # sort the numbers in ascending order to facilitate binary search + nums.sort() + + for x in range(len(nums)): + # find the maximum sum of two elements that is less than k, with the first element being nums[x] + y = search(nums, k - nums[x], x + 1) + if y > x: + # update max_sum with the maximum sum found so far + max_sum = max(max_sum, nums[x] + nums[y]) + + return max_sum + + +def search(nums: List[int], target: int, start: int) -> int: + """ + Searches for a number that is less than the target in a sorted list of numbers. + Uses binary search to achieve a time complexity of O(log n) and find the index j such that the sum + nums[i]+nums[j] < k. It takes the nums array, target value, and the start range of the search as input. + Args: + nums (List[int]): A sorted list of integers + target int: The target value to search for + start int: The starting index of the search range + Returns: + The index of the number that is less than the target, or -1 if no such number is found + """ + left, right = start, len(nums) - 1 + result = -1 + + while left <= right: + # calculate the midpoint of the search range + mid = (left + right) // 2 + if nums[mid] < target: + # update result to mid and move left to mid + 1 to look for larger values. + result = mid + left = mid + 1 + else: + # move right to mid - 1 to check smaller values. + right = mid - 1 + + return result diff --git a/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_1.png b/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_1.png new file mode 100644 index 00000000..6cc152af Binary files /dev/null and b/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_1.png differ diff --git a/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_2.png b/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_2.png new file mode 100644 index 00000000..36003369 Binary files /dev/null and b/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_2.png differ diff --git a/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_3.png b/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_3.png new file mode 100644 index 00000000..932cbe59 Binary files /dev/null and b/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_3.png differ diff --git a/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_4.png b/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_4.png new file mode 100644 index 00000000..f49930b3 Binary files /dev/null and b/algorithms/arrays/two_sum_less_k/images/examples/two_sum_less_k_example_4.png differ diff --git a/algorithms/arrays/two_sum_less_k/test_two_sum.py b/algorithms/arrays/two_sum_less_k/test_two_sum.py new file mode 100644 index 00000000..5fb56a94 --- /dev/null +++ b/algorithms/arrays/two_sum_less_k/test_two_sum.py @@ -0,0 +1,48 @@ +import unittest +from . import two_sum_less_than_k + + +class TwoSumLessKTestCase(unittest.TestCase): + def test_1(self): + """numbers = [4,2,11,2,5,3,5,8], target = 7""" + numbers = [4,2,11,2,5,3,5,8] + target = 7 + expected = 6 + actual = two_sum_less_than_k(numbers, target) + self.assertEqual(expected, actual) + + def test_2(self): + """numbers = [10,20,30], target = 15""" + numbers = [10, 20, 30] + target = 15 + expected = -1 + actual = two_sum_less_than_k(numbers, target) + self.assertEqual(expected, actual) + + def test_3(self): + """numbers = [34,23,1,24,75,33,54,8], k = 60""" + numbers = [34,23,1,24,75,33,54,8] + k = 60 + expected = 58 + actual = two_sum_less_than_k(numbers, k) + self.assertEqual(expected, actual) + + def test_4(self): + """numbers = [5,5,5,5,5,5], k = 15""" + numbers = [5,5,5,5,5,5] + k = 15 + expected = 10 + actual = two_sum_less_than_k(numbers, k) + self.assertEqual(expected, actual) + + def test_5(self): + """numbers = [1,2,3,4,5], k = 3""" + numbers = [1,2,3,4,5] + k = 3 + expected = -1 + actual = two_sum_less_than_k(numbers, k) + self.assertEqual(expected, actual) + + +if __name__ == "__main__": + unittest.main()