Skip to content

Commit cf8faf5

Browse files
authored
Update count-number-of-special-subsequences.py
1 parent 634208c commit cf8faf5

File tree

1 file changed

+8
-116
lines changed

1 file changed

+8
-116
lines changed
Lines changed: 8 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,14 @@
1-
# Time: O(1)
1+
# Time: O(n)
22
# Space: O(1)
33

4-
import math
5-
6-
74
class Solution(object):
8-
def minimumPerimeter(self, neededApples):
5+
def countSpecialSubsequences(self, nums):
96
"""
10-
:type neededApples: int
7+
:type nums: List[int]
118
:rtype: int
129
"""
13-
# find min r, s.t. 4r^3+6r^2+2r-neededApples >= 0
14-
# => by depressed cubic (https://en.wikipedia.org/wiki/Cubic_equation#Depressed_cubic)
15-
# let x = r+(6/(3*4)), r = x-(1/2)
16-
# 4(x-(1/2))^3+6(x-(1/2))^2+2(x-(1/2))-neededApples
17-
# = 4(x^3-3/2x^2+3/4x-1/8)
18-
# + 6(x^2-x+1/4)
19-
# + 2(x-1/2)
20-
# = 4x^3-x-neededApples >= 0
21-
#
22-
# find x, s.t. 4x^3-x-neededApples = 0 <=> x^3+(-1/4)x+(-neededApples/4) = 0
23-
# => by Cardano's formula (https://en.wikipedia.org/wiki/Cubic_equation#Cardano's_formula)
24-
# x^3 + px + q = 0, p = (-1/4), q = (-neededApples/4)
25-
# x = (-q/2 + ((q/2)^2+(p/3)^3)^(1/2)) + (-q/2 - ((q/2)^2+(p/3)^3)^(1/2))
26-
# r = x-(1/2)
27-
# => min r = ceil(r)
28-
29-
a, b, c, d = 4.0, 6.0, 2.0, float(-neededApples)
30-
p = (3*a*c-b**2)/(3*a**2) # -1/4.0
31-
q = (2*b**3-9*a*b*c+27*a**2*d)/(27*a**3) # -neededApples/4.0
32-
assert((q/2)**2+(p/3)**3 > 0)
33-
x = (-q/2 + ((q/2)**2+(p/3)**3)**0.5)**(1/3.0) + \
34-
(-q/2 - ((q/2)**2+(p/3)**3)**0.5)**(1/3.0)
35-
return 8*int(math.ceil(x - b/(3*a)))
36-
37-
38-
# Time: O(1)
39-
# Space: O(1)
40-
class Solution2(object):
41-
def minimumPerimeter(self, neededApples):
42-
"""
43-
:type neededApples: int
44-
:rtype: int
45-
"""
46-
# r+r , (r-1)+r, ..., 1+r, 0+r , 1+r, ..., (r-1)+r, r+r
47-
# r+r-1, 0+(r-1), r+(r-1)
48-
# . . .
49-
# . . .
50-
# . . .
51-
# r+1, (r-1)+1, ..., 1+1, 1+0, 1+1, ..., (r-1)+1, r+1
52-
# r+0, (r-1)+0, ..., 1+0, 0+0, 1+0, ..., (r-1)+0, r+0
53-
# r+1, (r-1)+1, ..., 1+1, 1+0, 1+1, ..., (r-1)+1, r+1
54-
# . . .
55-
# . . .
56-
# . . .
57-
# r+r-1, 0+(r-1), r+(r-1)
58-
# r+r , (r-1)+r, ..., 1+r, 0+r , 1+r, ..., r+(r-1), r+r
59-
#
60-
# each up/down direction forms an arithmetic sequence, there are 2r+1 columns
61-
# => 2*(1+r)*r/2 * (2r+1)
62-
#
63-
# each left/right direction forms an arithmetic sequence, there are 2r+1 rows
64-
# => 2*(1+r)*r/2 * (2r+1)
65-
#
66-
# => total = 2 * 2*(1+r)*r/2 * (2r+1) = r*(2r+1)*(2r+2) = 4r^3+6r^2+2r
67-
# => find min r, s.t. (2r)(2r+1)*(2r+2) >= 2*neededApples
68-
# => find min x = 2r+2, s.t. (x-2)(x-1)(x) >= 2*neededApples
69-
70-
x = int((2*neededApples)**(1/3.0))
71-
x -= x%2
72-
assert((x-2)*(x-1)*x < 2*neededApples)
73-
assert((x+2)**3 >= 2*neededApples)
74-
x += 2
75-
if (x-2)*(x-1)*x < 2*neededApples:
76-
x += 2
77-
return 8*(x-2)//2
78-
79-
80-
# Time: O(logn)
81-
# Space: O(1)
82-
class Solution3(object):
83-
def minimumPerimeter(self, neededApples):
84-
"""
85-
:type neededApples: int
86-
:rtype: int
87-
"""
88-
# 2r, 2r-1, ..., r+1, r , r+1, ..., 2*r-1, 2*r
89-
# 2r-1 r-1, 2r-1
90-
# . . .
91-
# . . .
92-
# . . .
93-
# r+1 r, ..., 2, 1, 2, ..., r, r+1
94-
# r, r-1, ..., 1, 0, 1, ..., r-1, r
95-
# r+1 r, ..., 2, 1, 2, ..., r, r+1
96-
# . . .
97-
# . . .
98-
# . . .
99-
# 2r-1 r-1, 2r-1
100-
# 2r, 2r-1, ..., r+1, r , r+1, ..., 2*r-1, 2*r
101-
#
102-
# the sum of each row/col forms an arithmetic sequence
103-
# => let ai = (((r + (r-1) + ... + r + 0) + (0 + 1 + 2 + ... + r)) - 0) + i*(2r+1)
104-
# = (2*(0+r)*(r+1)/2-0) + i*(2r+1)
105-
# = r*(r+1) + i*(2r+1)
106-
# => total = 2*(a0 + a1 + ... ar) - a0
107-
# = 2*(r*(r+1) + r*(r+1) + r*(2r+1)))*(r+1)/2 - r*(r+1)
108-
# = r*(4r+3)*(r+1)-r*(r+1)
109-
# = 4r^3+6r^2+2r
110-
# => find min r, s.t. 4r^3+6r^2+2r >= neededApples
111-
112-
def check(neededApples, x):
113-
return r*(2*r+1)*(2*r+2) >= neededApples
114-
115-
left, right = 1, int((neededApples/4.0)**(1/3.0))
116-
while left <= right:
117-
mid = left + (right-left)//2
118-
if check(neededApples, mid):
119-
right = mid-1
120-
else:
121-
left = mid+1
122-
return 8*left
10+
MOD = 10**9+7
11+
dp = [0]*3
12+
for x in nums:
13+
dp[x] = ((dp[x]+dp[x])%MOD+(dp[x-1] if x-1 >= 0 else 1))%MOD
14+
return dp[-1]

0 commit comments

Comments
 (0)