Skip to content

Commit 939706a

Browse files
author
weiy
committed
3 sum with multiplicity medium
1 parent 3b71692 commit 939706a

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed

Diff for: Array/3SumWithMultiplicity.py

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
"""
2+
Given an integer array A, and an integer target, return the number of tuples i, j, k such that i < j < k and A[i] + A[j] + A[k] == target.
3+
4+
As the answer can be very large, return it modulo 10^9 + 7.
5+
6+
7+
8+
Example 1:
9+
10+
Input: A = [1,1,2,2,3,3,4,4,5,5], target = 8
11+
Output: 20
12+
Explanation:
13+
Enumerating by the values (A[i], A[j], A[k]):
14+
(1, 2, 5) occurs 8 times;
15+
(1, 3, 4) occurs 8 times;
16+
(2, 2, 4) occurs 2 times;
17+
(2, 3, 3) occurs 2 times.
18+
Example 2:
19+
20+
Input: A = [1,1,2,2,2,2], target = 5
21+
Output: 12
22+
Explanation:
23+
A[i] = 1, A[j] = A[k] = 2 occurs 12 times:
24+
We choose one 1 from [1,1] in 2 ways,
25+
and two 2s from [2,2,2,2] in 6 ways.
26+
27+
28+
Note:
29+
30+
3 <= A.length <= 3000
31+
0 <= A[i] <= 100
32+
0 <= target <= 300
33+
34+
35+
思路:
36+
37+
首先排序,然后按照正常的3sum。
38+
39+
这样做有个问题:
40+
重复的太多会超级耗时,我的做法是重新生成列表,若超过三个,则按3个加入。
41+
42+
继续之前的思路所要生成的重复的次数:
43+
[1,1,2,2,3,3,4,4,5,5]
44+
45+
1 2 5
46+
47+
1出现了两次,2出现了两次,5出现了两次,那么总次数为 2*2*2 = 8
48+
49+
(2, 2, 4)
50+
51+
2出现了两次,4出现了两次,不过 2 在这个子问题中也出现了两次,所以总数应为 2的总数-1的阶加 * 4出现的总数。
52+
53+
sum(range(2)) * 2
54+
55+
如果是
56+
57+
0 0 0
58+
0
59+
60+
这样子问题是
61+
0 0 0,出现三次的情况。
62+
63+
若原列表中出现了 3 次,那么只有 1种情况。
64+
4 次,则是 4 种。
65+
5 次,则是 10 种。
66+
6 次,则是 20 种。
67+
68+
这个次数其实是 3 次则是 sum(range(2)) + sum(range(1))
69+
4 次则是 sum(range(3)) + sum(range(2)) + sum(range(1))
70+
...
71+
72+
按照这个思路我的做法是首先生成最大次数的阶加结果。
73+
74+
可以 passed. 320ms。 运行测试的话每次都要 生成阶加列表,如果可以只生成一次到是可以减少很大运行时间,可能还有其他方法?
75+
76+
测试地址:
77+
https://leetcode.com/problems/3sum-with-multiplicity/description/
78+
79+
"""
80+
class Solution(object):
81+
def threeSumMulti(self, A, target):
82+
"""
83+
:type A: List[int]
84+
:type target: int
85+
:rtype: int
86+
"""
87+
mod = 10**9 + 7
88+
89+
def get_multiple(time, all_times):
90+
if time==1:
91+
return all_times
92+
elif time==2:
93+
return sum(range(all_times))
94+
elif time==3:
95+
return sum(plus[:all_times])
96+
97+
x = {}
98+
for j in set(A):
99+
x[j] = A.count(j)
100+
101+
maxes = max(x, key=lambda t: x[t])
102+
103+
plus = [sum(range(i)) for i in range(x[maxes])]
104+
105+
106+
A = []
107+
108+
for i in sorted(x.keys()):
109+
if x[i] > 3:
110+
A.extend([i]*3)
111+
else:
112+
A.extend([i]*x[i])
113+
result = 0
114+
length = len(A) - 1
115+
sets = set()
116+
for i in range(length):
117+
t = target - A[i]
118+
start = i+1
119+
end = length
120+
121+
while start < end:
122+
if A[start] + A[end] == t:
123+
# pass
124+
_ = [A[i], A[start], A[end]]
125+
y = {e:_.count(e) for e in set(_)}
126+
127+
_ = "{}{}{}".format(*_)
128+
129+
if _ in sets:
130+
start += 1
131+
continue
132+
133+
c = 1
134+
for g in y:
135+
c *= get_multiple(y[g], x[g])
136+
result += c
137+
sets.add(_)
138+
start += 1
139+
140+
if A[start] + A[end] > t:
141+
end -= 1
142+
else:
143+
start += 1
144+
return result % mod

0 commit comments

Comments
 (0)