-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlc1_two_sum.py
170 lines (128 loc) · 5.86 KB
/
lc1_two_sum.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
"""
Given an array of integers nums and an integer target,
return indices of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution,
and you may not use the same element twice.
You can return the answer in any order.
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]
"""
import unittest
def two_sum_brute_force(nums: list[int], target: int) -> tuple[int, int]:
"""
Returns the indices of two numbers in the list that sum up to the target.
This function takes in a list of integers `nums` and an integer `target`,
and returns a tuple of two indices `i` and `j` such that `nums[i] + nums[j] == target`.
If no such indices exist, it returns `-1, -1`.
Algorithm Used: Brute Force
Time Complexity: O(n^2)
because it needs to traverse each element of the list nums twice
Space Complexity: O(1)
because it only uses a constant amount of space to store the indices i and j
and the temporary variables i_num and j_num.
"""
for i, i_num in enumerate(nums):
for j, j_num in enumerate(nums[i+1:], start=i+1):
if i_num + j_num == target:
return i, j
return -1, -1
def two_sum_using_two_pointers(nums: list[int], target: int) -> tuple[int, int]:
"""Two sum using two pointers
Algorithm Used: Two Pointers
Time Complexity: O(n)
because it needs to traverse the list only once
Space Complexity: O(1)
because it only uses a constant amount of space to store the indices i and j
"""
# Sort the number before proceed with the two pointers algorithm
nums.sort()
left, right = 0, len(nums) - 1
while left < right:
if nums[left] + nums[right] > target:
right -= 1
elif nums[left] + nums[right] < target:
left += 1
else:
return left, right
return -1, -1
class TestTwoSumBruteForce(unittest.TestCase):
"""
Test case for the `two sum` problem.
This test case verifies the behavior of the `two sum` problem
by checking the correctness of its output for various input scenarios.
The function takes in a list of integers `nums` and a target integer `target`,
and returns a tuple of two indices `i` and `j` such that `nums[i] + nums[j] == target`.
If no such indices exist, it returns `-1, -1`.
The test cases cover the following scenarios:
1. Test case 1: Two unique indices with a valid sum.
- Input: `nums = [2, 7, 11, 15]`, `target = 9`
- Expected output: `(0, 1)`
2. Test case 2: Two unique indices with an invalid sum.
- Input: `nums = [2, 7, 11, 15]`, `target = 17`
- Expected output: `(-1, -1)`
3. Test case 3: No indices with a valid sum.
- Input: `nums = [2, 7, 11, 15]`, `target = 30`
- Expected output: `(-1, -1)`
4. Test case 4: Empty list.
- Input: `nums = []`, `target = 9`
- Expected output: `(-1, -1)`
5. Test case 5: Single element list.
- Input: `nums = [5]`, `target = 10`
- Expected output: `(-1, -1)`
6. Test case 6: List with duplicate elements.
- Input: `nums = [2, 7, 11, 11, 15]`, `target = 16`
- Expected output: `(1, 4)`
7. Test case 7: List with negative numbers.
- Input: `nums = [-1, 0, 1, 2, 3]`, `target = 0`
- Expected output: `(0, 4)`
"""
def test_two_sum_brute_force(self) -> None:
"""
This test case is part of the unit tests for the `two_sum_brute_force` function.
"""
# Test case 1: Two unique indices with a valid sum
self.assertTupleEqual(two_sum_brute_force([2, 7, 11, 15], 9), (0, 1))
# Test case 2: Two unique indices with an invalid sum
self.assertTupleEqual(two_sum_brute_force([2, 7, 11, 15], 17), (0, 3))
# Test case 3: No indices with a valid sum
self.assertTupleEqual(two_sum_brute_force(
[2, 7, 11, 15], 30), (-1, -1))
# Test case 4: Empty list
self.assertTupleEqual(two_sum_brute_force([], 9), (-1, -1))
# Test case 5: Single element list
self.assertTupleEqual(two_sum_brute_force([5], 10), (-1, -1))
# Test case 6: List with duplicate elements
self.assertTupleEqual(two_sum_brute_force(
[2, 7, 11, 11, 15], 16), (-1, -1))
# Test case 7: List with negative numbers
self.assertTupleEqual(two_sum_brute_force([-1, 0, 1, 2, 3], 0), (0, 2))
def test_two_sum_two_pointers(self) -> None:
"""
This test case is part of the unit tests for the `two_sum_using_two_pointers` function.
"""
# Test case 1: Two unique indices with a valid sum
self.assertTupleEqual(two_sum_using_two_pointers([2, 7, 11, 15], 9), (0, 1))
# Test case 2: Two unique indices with an invalid sum
self.assertTupleEqual(two_sum_using_two_pointers([2, 7, 11, 15], 17), (0, 3))
# Test case 3: No indices with a valid sum
self.assertTupleEqual(two_sum_using_two_pointers(
[2, 7, 11, 15], 30), (-1, -1))
# Test case 4: Empty list
self.assertTupleEqual(two_sum_using_two_pointers([], 9), (-1, -1))
# Test case 5: Single element list
self.assertTupleEqual(two_sum_using_two_pointers([5], 10), (-1, -1))
# Test case 6: List with duplicate elements
self.assertTupleEqual(two_sum_using_two_pointers(
[2, 7, 11, 11, 15], 16), (-1, -1))
# Test case 7: List with negative numbers
self.assertTupleEqual(two_sum_using_two_pointers([-1, 0, 1, 2, 3], 0), (0, 2))
if __name__ == '__main__':
unittest.main()