-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path0015-3sum.py
More file actions
70 lines (62 loc) · 2.13 KB
/
0015-3sum.py
File metadata and controls
70 lines (62 loc) · 2.13 KB
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
"""
15. 3Sum
Submitted: March 2, 2026
Runtime: 1712 ms (beats 7.32%)
Memory: 28.08 MB (beats 5.36%)
"""
from collections import Counter
class Solution:
def twoSum(self, used: int) -> list[list[int]]:
if used == 0:
return [[0, 0]] if self.nums_count[0] >= 3 else []
elif used < 0:
# get largest two
a, b = self.nums_2largest
# could never add up
if a + b + used < 0:
# not possible
return []
elif used > 0:
# smallest two
a, b = self.nums_2smallest
# could never add up
if a + b + used > 0:
# not possible
return []
target = -used
nums = (
num for num in self.nums if num != used or self.nums_count[num] > 1
)
res = []
for num in nums:
diff = target - num
# to prevent going through the array with two pairs
if diff > num: continue
# sanity check here to make sure we don't use numbers too many times
# used == num == diff != 0 since optimization at top of program
if used == num == diff:
continue
elif used == diff:
if self.nums_count[used] < 2: continue
elif used == num or num == diff:
if self.nums_count[num] < 2: continue
if num == diff or diff in self.nums_count:
res.append((num, diff))
return res
def threeSum(self, nums: list[int]) -> list[list[int]]:
if len(set(nums)) == 1:
return [[0, 0, 0]] if nums[0] == 0 else []
self.nums = set(nums)
nums_sorted = sorted(nums)
self.nums_2largest = nums_sorted[-2:]
self.nums_2smallest = nums_sorted[:2]
del nums_sorted
self.nums_count = Counter(nums)
res = []
for num in self.nums:
twoposs = self.twoSum(num)
if not twoposs:
continue
res.extend((num, *t) for t in twoposs)
res = sorted(tuple(set(tuple(sorted(t)) for t in res)))
return res