Skip to content

Commit f1ddcfc

Browse files
Chris WuChris Wu
Chris Wu
authored and
Chris Wu
committed
no message
1 parent 9ddb4dd commit f1ddcfc

File tree

3 files changed

+148
-1
lines changed

3 files changed

+148
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Leetcode Python Solution
2-
1. This is my Python (2.7) solution on Leetcode. The question is at `problems/the-file-name/`. For example, `merge-sorted-array.py`'s question is at `https://leetcode.com/problems/merge-sorted-array/`.
2+
1. This is my Python (2.7) Leetcode solution. The question is at `problems/the-file-name/`. For example, `merge-sorted-array.py`'s question is at `https://leetcode.com/problems/merge-sorted-array/`.
33

44
2. I really take time tried to make the best solution or explaination.
55
Because I wanted to help others like me.

problems/word-ladder.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""
2+
This problem is better using BFS. Because we need to find the shortest step.
3+
Using DFS, we may eventually find the `endWord` but not the shortest path.
4+
5+
First, build a memo so that we can find the related word without going through a~z every time we pop out a new word from queue.
6+
So for example
7+
```
8+
wordList = ["hot","dot","dog","lot","log","cog"]
9+
10+
memo = {
11+
'lo#': ['lot', 'log'],
12+
'l#t': ['lot'],
13+
'#ot': ['hot', 'dot', 'lot'],
14+
'h#t': ['hot'],
15+
'do#': ['dot', 'dog'],
16+
'l#g': ['log'],
17+
'co#': ['cog'],
18+
'#og': ['dog', 'log', 'cog'],
19+
'd#g': ['dog'],
20+
'd#t': ['dot'],
21+
'c#g': ['cog'],
22+
'ho#': ['hot']
23+
}
24+
```
25+
26+
Second build a queue to BFS from `beginWord` to `endWord`.
27+
Everytime we pop a word we first check if it is visited.
28+
Then check if it is `endWord`, if true, return the steps.
29+
If not, put all the neighbor to the queue.
30+
31+
If the queue ended and we did not find the `endWord`, return 0.
32+
33+
The time complexity is O(W*C), W is the word count, C is the character count in each word.
34+
The space complexity is also O(W*C).
35+
"""
36+
class Solution(object):
37+
def ladderLength(self, beginWord, endWord, wordList):
38+
memo = collections.defaultdict(list)
39+
for word in wordList:
40+
for i in xrange(len(word)):
41+
memo[word[:i]+'#'+word[i+1:]].append(word)
42+
43+
seen = set()
44+
q = collections.deque([(beginWord, 1)])
45+
while q:
46+
word, steps = q.popleft()
47+
if word==endWord: return steps
48+
seen.add(word)
49+
50+
for i in xrange(len(word)):
51+
for next_word in memo[word[:i]+'#'+word[i+1:]]:
52+
if next_word not in seen:
53+
q.append((next_word, steps+1))
54+
return 0
55+
56+
"""
57+
When comparing to other solution, I made some changes.
58+
Which is the timing of adding the word to the `visited` hash-set.
59+
I think by adding the word to the hash-set in the for loop, makes the queue smaller, so it would be slightly faster.
60+
But the time complexity is totally the same.
61+
"""
62+
class Solution(object):
63+
def ladderLength(self, beginWord, endWord, wordList):
64+
memo = collections.defaultdict(list)
65+
for word in wordList:
66+
for i in xrange(len(word)):
67+
memo[word[:i]+'#'+word[i+1:]].append(word)
68+
69+
seen = set()
70+
q = collections.deque([(beginWord, 1)])
71+
while q:
72+
word, steps = q.popleft()
73+
if word==endWord: return steps
74+
75+
for i in xrange(len(word)):
76+
for next_word in memo[word[:i]+'#'+word[i+1:]]:
77+
if next_word not in seen:
78+
q.append((next_word, steps+1))
79+
seen.add(next_word)
80+
return 0
81+
82+
class Solution(object):
83+
def ladderLength(self, beginWord, endWord, wordList):
84+
wordList = set(wordList)
85+
seen = set()
86+
q = collections.deque([(beginWord, 1)])
87+
while q:
88+
word, steps = q.popleft()
89+
if word==endWord: return steps
90+
91+
for i in xrange(len(word)):
92+
for alphabet in 'abcdefghijklmnopqrstuvwxyz':
93+
next_word = word[:i]+alphabet+word[i+1:]
94+
if next_word not in seen and next_word in wordList:
95+
q.append((next_word, steps+1))
96+
seen.add(next_word)
97+
return 0

problems/word-search-ii.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# TLE
2+
class Solution(object):
3+
def findWords(self, board, words):
4+
def getNeighbor(i, j):
5+
opt = []
6+
if i+1<M: opt.append((i+1, j))
7+
if j+1<N: opt.append((i, j+1))
8+
if i-1>=0: opt.append((i-1, j))
9+
if j-1>=0: opt.append((i, j-1))
10+
return opt
11+
12+
def dfs(i, j, l, word):
13+
if word in found: return
14+
if board[i][j]!=word[l]: return
15+
16+
if l==len(word)-1 and board[i][j]==word[l]:
17+
opt.append(word)
18+
found.add(word)
19+
return
20+
21+
char = board[i][j]
22+
board[i][j] = '#'
23+
24+
for ni, nj in getNeighbor(i, j):
25+
dfs(ni, nj, l+1, word)
26+
27+
board[i][j] = char
28+
29+
opt = []
30+
M = len(board)
31+
N = len(board[0])
32+
found = set()
33+
34+
for i in xrange(M):
35+
for j in xrange(N):
36+
for word in words:
37+
if word not in found:
38+
dfs(i, j, 0, word)
39+
return opt
40+
41+
42+
board = [
43+
['o','a','a','n'],
44+
['e','t','a','e'],
45+
['i','h','k','r'],
46+
['i','f','l','v']
47+
]
48+
words = ["oath","pea","eat","rain"]
49+
50+
print Solution().findWords(board, words)

0 commit comments

Comments
 (0)