Skip to content

Commit aa4a2c0

Browse files
authored
Create subsequences-with-a-unique-middle-mode-ii.py
1 parent af8fe44 commit aa4a2c0

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Time: O(n)
2+
# Space: O(n)
3+
4+
import collections
5+
6+
7+
# freq table, prefix sum, combinatorics
8+
class Solution(object):
9+
def subsequencesWithMiddleMode(self, nums):
10+
"""
11+
:type nums: List[int]
12+
:rtype: int
13+
"""
14+
def nC2(x):
15+
return x*(x-1)//2
16+
17+
MOD = 10**9+7
18+
result = 0
19+
left = collections.defaultdict(int)
20+
right = collections.defaultdict(int)
21+
for x in nums:
22+
right[x] += 1
23+
left_x_sq = 0 # sum(left[x]^2 for x != v)
24+
right_x_sq = sum(v**2 for v in right.itervalues()) # sum(right[x]^2 for x != v)
25+
left_x_right_x = 0 # sum(left[x]*right[x] for x != v)
26+
left_x_sq_right_x = 0 # sum(left[x]^2*right[x] for x != v)
27+
left_x_right_x_sq = 0 # sum(left[x]*right[x]^2 for x != v)
28+
for i, v in enumerate(nums):
29+
left_x_sq -= left[v]**2
30+
right_x_sq -= right[v]**2
31+
left_x_right_x -= left[v]*right[v]
32+
left_x_sq_right_x -= left[v]**2*right[v]
33+
left_x_right_x_sq -= left[v]*right[v]**2
34+
right[v] -= 1
35+
36+
l, r = i, len(nums)-(i+1)
37+
# all possibles
38+
result += nC2(l)*nC2(r)
39+
# only mid is a
40+
result -= nC2(l-left[v])*nC2(r-right[v])
41+
# bb/a/ac
42+
# sum((left[x]*(left[x]-1)//2)*right[v]*((r-right[v])-right[x]) for x != v)
43+
result -= ((left_x_sq-(l-left[v]))*(r-right[v])-(left_x_sq_right_x-left_x_right_x))*right[v]//2
44+
# ac/a/bb
45+
# sum(left[v]*((l-left[v])-left[x])*(right[x]*(right[x]-1)//2) for x != v)
46+
result -= ((right_x_sq-(r-right[v]))*(l-left[v])-(left_x_right_x_sq-left_x_right_x))*left[v]//2
47+
# ab/a/bc
48+
# sum(left[v]*left[x]*right[x]*((r-right[v])-right[x]) for x != v)
49+
result -= left[v]*left_x_right_x*(r-right[v])-left[v]*left_x_right_x_sq
50+
# bc/a/ab
51+
# sum(left[x]*((l-left[v])-left[x])*right[v]*right[x] for x != v)
52+
result -= right[v]*left_x_right_x*(l-left[v])-right[v]*left_x_sq_right_x
53+
# bb/a/ab
54+
# sum((left[x]*(left[x]-1)//2)*right[v]*right[x] for x != v)
55+
result -= right[v]*(left_x_sq_right_x-left_x_right_x)//2
56+
# ab/a/bb
57+
# sum((right[x]*(right[x]-1)//2)*left[v]*left[x] for x != v)
58+
result -= left[v]*(left_x_right_x_sq-left_x_right_x)//2
59+
60+
left[v] += 1
61+
left_x_sq += left[v]**2
62+
right_x_sq += right[v]**2
63+
left_x_right_x += left[v]*right[v]
64+
left_x_sq_right_x += left[v]**2*right[v]
65+
left_x_right_x_sq += left[v]*right[v]**2
66+
return result % MOD

0 commit comments

Comments
 (0)