Skip to content

Commit 66f6f8d

Browse files
author
wuduhren
committed
update
1 parent 048b1c8 commit 66f6f8d

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""
2+
Time: O(4^N * N), there are around 4^N of combination. Each taking O(N) to form.
3+
Space: O(N). O(N) for recursion stack. O(N). O(N) for `combination`. O(N+N) ~= O(N).
4+
"""
5+
class Solution:
6+
def letterCombinations(self, digits: str) -> List[str]:
7+
def helper(i):
8+
if i==len(digits):
9+
ans.append(''.join(combination))
10+
return
11+
12+
for c in mapping[digits[i]]:
13+
combination.append(c)
14+
helper(i+1)
15+
combination.pop()
16+
17+
mapping = {'2': ('a', 'b', 'c'), '3': ('d', 'e', 'f'),
18+
'4': ('g', 'h', 'i'), '5': ('j', 'k', 'l'), '6': ('m', 'n', 'o'),
19+
'7': ('p', 'q', 'r', 's'), '8': ('t', 'u', 'v'), '9': ('w', 'x', 'y', 'z')}
20+
21+
if not digits: return []
22+
ans = []
23+
combination = []
24+
helper(0)
25+
return ans
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
`helper(i)` finds all the palindrome substring from i to j see if we can get an answer by recursively calling `helper(j+1)`.
3+
4+
Time: O(2^N * N), for a string length S, there will be 2^N combination of substrings. For each substring, it will take O(N) to test if they are all palindrome.
5+
Space: O(N). `partition` will takes O(N) and recursion stack will also take O(N). O(N + N) ~= O(N)
6+
"""
7+
class Solution:
8+
def partition(self, s: str) -> List[List[str]]:
9+
def helper(i):
10+
if i>=len(s):
11+
ans.append(partition.copy())
12+
return
13+
14+
for j in range(i, len(s)):
15+
if isPalindrome(i, j):
16+
partition.append(s[i:j+1])
17+
helper(j+1)
18+
partition.pop()
19+
20+
def isPalindrome(i, j):
21+
while i<=j:
22+
if s[i]!=s[j]: return False
23+
i += 1
24+
j -= 1
25+
return True
26+
27+
ans = []
28+
partition = []
29+
helper(0)
30+
return ans
31+
32+
"""
33+
If you look closely you can see that we execute `isPalindrome` on many repeated substrings.
34+
We can optimize this by storing the result in `dp` and reuse it.
35+
Since all the less difference i and j (shorter substring s[i:j+1]) will be process first in the `isPalindrome`.
36+
When checking if s[i:j+1] is a palindrome or not, we can simply check the if s[i]==s[j] and the previous result (dp[i+1][j-1])
37+
38+
Time: O(2^N * N), The overall time complexity is the same, but isPalindrome is actually a lot faster.
39+
Space: O(N^2) for `dp`.
40+
"""
41+
class Solution:
42+
def partition(self, s: str) -> List[List[str]]:
43+
def helper(i):
44+
if i>=N:
45+
ans.append(partition.copy())
46+
return
47+
48+
for j in range(i, N):
49+
if isPalindrome(i, j):
50+
partition.append(s[i:j+1])
51+
helper(j+1)
52+
partition.pop()
53+
54+
def isPalindrome(i, j):
55+
dp[i][j] = i==j or (j-i==1 and s[i]==s[j]) or (s[i]==s[j] and dp[i+1][j-1]) #len==1 palindrome or len==2 palindrome or len>=3 palindrome
56+
return dp[i][j]
57+
58+
N = len(s)
59+
ans = []
60+
partition = []
61+
dp = [[False]*N for _ in range(N)]
62+
63+
helper(0)
64+
return ans

problems/python3/word-search.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution:
2+
def exist(self, board: List[List[str]], word: str) -> bool:
3+
def helper(x, i, j):
4+
if i<0 or i>=N or j<0 or j>=M: return False
5+
if (i, j) in usedWords: return False
6+
usedWords.add((i, j))
7+
8+
if word[x]==board[i][j]:
9+
if x==len(word)-1:
10+
return True
11+
else:
12+
if helper(x+1, i+1, j): return True
13+
if helper(x+1, i, j+1): return True
14+
if helper(x+1, i-1, j): return True
15+
if helper(x+1, i, j-1): return True
16+
17+
18+
usedWords.remove((i, j))
19+
return False
20+
21+
usedWords = set()
22+
N = len(board)
23+
M = len(board[0])
24+
for i in range(N):
25+
for j in range(M):
26+
if helper(0, i, j): return True
27+
return False

0 commit comments

Comments
 (0)