1
+ // Runtime : 1026 ms (Top 83.52 % ) | Memory : 55.5 MB (Top 82.18 % )
1
2
from functools import lru_cache
2
3
class Solution :
3
4
def possiblyEquals (self , s1 : str , s2 : str ) -> bool :
4
-
5
+
5
6
def getValidPrefixLength (s ,start ):
6
7
end = start
7
8
while end < len (s ) and s [end ].isdigit (): end += 1
8
9
return end
9
-
10
+
10
11
@lru_cache (None )
11
- def possibleLengths (s ):
12
+ def possibleLengths (s ):
12
13
"""Return all possible lengths represented by numeric string s."""
13
14
ans = {int (s )}
14
15
for i in range (1 , len (s )):
15
16
# add all lengths by splitting numeric string s at i
16
17
ans |= {x + y for x in possibleLengths (s [:i ]) for y in possibleLengths (s [i :])}
17
18
return ans
18
-
19
+
19
20
@lru_cache (None )
20
- def dp (i , j , diff ):
21
+ def dp (i , j , diff ):
21
22
"""Return True if s1[i:] matches s2[j:] with given differences."""
22
-
23
+
23
24
# If both have reached end return true if none of them are leading
24
25
if i == len (s1 ) and j == len (s2 ): return diff == 0
25
-
26
+
26
27
# s1 has not reached end and s1 starts with a digit
27
- if i < len (s1 ) and s1 [i ].isdigit ():
28
+ if i < len (s1 ) and s1 [i ].isdigit ():
28
29
i2 = getValidPrefixLength (s1 ,i )
29
- for L in possibleLengths (s1 [i :i2 ]):
30
- # substract since lead of s2 decreases by L
31
- if dp (i2 , j , diff - L ): return True
32
-
30
+ for L in possibleLengths (s1 [i :i2 ]):
31
+ # substract since lead of s2 decreases by L
32
+ if dp (i2 , j , diff - L ): return True
33
+
33
34
# s2 has not reached end and s2 starts with a digit
34
- elif j < len (s2 ) and s2 [j ].isdigit ():
35
+ elif j < len (s2 ) and s2 [j ].isdigit ():
35
36
j2 = getValidPrefixLength (s2 ,j )
36
- for L in possibleLengths (s2 [j :j2 ]):
37
+ for L in possibleLengths (s2 [j :j2 ]):
37
38
# add since lead of s2 increase by L
38
- if dp (i , j2 , diff + L ): return True
39
-
39
+ if dp (i , j2 , diff + L ): return True
40
+
40
41
# if none of them have integer prefix or a lead over the other
41
- elif diff == 0 :
42
- # if only one of them has reached end or current alphabets are not the same
43
- if i == len (s1 ) or j == len (s2 ) or s1 [i ] != s2 [j ]: return False
42
+ elif diff == 0 :
43
+ # if only one of them has reached end or current alphabets are not the same
44
+ if i == len (s1 ) or j == len (s2 ) or s1 [i ] != s2 [j ]: return False
44
45
# skip same alphabets
45
46
return dp (i + 1 , j + 1 , 0 )
46
-
47
- # if none of them have integer prefix & s2 lead over s1
48
- elif diff > 0 :
47
+
48
+ # if none of them have integer prefix & s2 lead over s1
49
+ elif diff > 0 :
49
50
# no s1 to balance s2's lead
50
51
if i == len (s1 ): return False
51
52
# move s1 pointer forward and reduce diff
52
53
return dp (i + 1 , j , diff - 1 )
53
-
54
+
54
55
# if none of them have integer prefix & s1 lead over s2
55
- else :
56
+ else :
56
57
# no s2 to balance s1's lead
57
- if j == len (s2 ): return False
58
+ if j == len (s2 ): return False
58
59
# move s2 pointer forward and increase diff
59
60
return dp (i , j + 1 , diff + 1 )
60
-
61
+
61
62
# start with starts of both s1 and s2 with no lead by any of them
62
- return dp (0 , 0 , 0 )
63
+ return dp (0 , 0 , 0 )
0 commit comments