-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
count-beautiful-splits-in-an-array.py
84 lines (77 loc) · 2.55 KB
/
count-beautiful-splits-in-an-array.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
# Time: O(n^2)
# Space: O(n)
# z-function
class Solution(object):
def beautifulSplits(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# Template: https://cp-algorithms.com/string/z-function.html
def z_function(s): # Time: O(n), Space: O(n)
z = [0]*len(s)
l, r = 0, 0
for i in xrange(1, len(z)):
if i <= r:
z[i] = min(r-i+1, z[i-l])
while i+z[i] < len(z) and s[z[i]] == s[i+z[i]]:
z[i] += 1
if i+z[i]-1 > r:
l, r = i, i+z[i]-1
return z
result = 0
z0 = z_function(nums)
for i in xrange(1, len(nums)-1):
zi = z_function(nums[i:])
for j in xrange(i+1, len(nums)):
if (z0[i] >= i and j-i >= i) or zi[j-i] >= j-i:
result += 1
return result
# Time: O(n^2)
# Space: O(n^2)
# dp
class Solution2(object):
def beautifulSplits(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp = [[0]*len(nums) for _ in xrange(len(nums))]
for i in reversed(xrange(len(nums))):
for j in xrange(i+1, len(dp)):
dp[i][j] = 1+(dp[i+1][j+1] if j+1 < len(nums) else 0) if nums[i] == nums[j] else 0
result = 0
for i in xrange(1, len(nums)-1):
for j in xrange(i+1, len(nums)):
if (dp[0][i] >= i and j-i >= i) or dp[i][j] >= j-i:
result += 1
return result
# Time: O(n^2)
# Space: O(n)
# z-function
class Solution_TLE(object):
def beautifulSplits(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# Template: https://cp-algorithms.com/string/z-function.html
def z_function(s, left, right): # Time: O(n), Space: O(n)
z = [0]*(right-left+1)
l, r = 0, 0
for i in xrange(1, len(z)):
if i <= r:
z[i] = min(r-i+1, z[i-l])
while i+z[i] < len(z) and s[left+z[i]] == s[left+i+z[i]]:
z[i] += 1
if i+z[i]-1 > r:
l, r = i, i+z[i]-1
return z
result = 0
z0 = z_function(nums, 0, len(nums)-1)
for i in xrange(1, len(nums)-1):
zi = z_function(nums, i, len(nums)-1)
for j in xrange(i+1, len(nums)):
if (z0[i] >= i and j-i >= i) or zi[j-i] >= j-i:
result += 1
return result