Skip to content

Commit f8ac53b

Browse files
committed
Word Ladder II/ Single Number II
1 parent 3872ae0 commit f8ac53b

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

126 Word Ladder II.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
'''
2+
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
3+
4+
Only one letter can be changed at a time
5+
Each intermediate word must exist in the word list
6+
For example,
7+
8+
Given:
9+
beginWord = "hit"
10+
endWord = "cog"
11+
wordList = ["hot","dot","dog","lot","log"]
12+
Return
13+
[
14+
["hit","hot","dot","dog","cog"],
15+
["hit","hot","lot","log","cog"]
16+
]
17+
Note:
18+
All words have the same length.
19+
All words contain only lowercase alphabetic characters.
20+
'''
21+
22+
class Solution(object):
23+
def findLadders(self, beginWord, endWord, wordlist):
24+
"""
25+
:type beginWord: str
26+
:type endWord: str
27+
:type wordlist: Set[str]
28+
:rtype: List[List[int]]
29+
"""
30+
31+
def bfs(front_level, end_level, is_forward, word_set, path_dic):
32+
if len(front_level) == 0:
33+
return False
34+
if len(front_level) > len(end_level):
35+
return bfs(end_level, front_level, not is_forward, word_set, path_dic)
36+
for word in (front_level | end_level):
37+
word_set.discard(word)
38+
next_level = set()
39+
done = False
40+
while front_level:
41+
word = front_level.pop()
42+
for c in 'abcdefghijklmnopqrstuvwxyz':
43+
for i in range(len(word)):
44+
new_word = word[:i] + c + word[i + 1:]
45+
if new_word in end_level:
46+
done = True
47+
add_path(word, new_word, is_forward, path_dic)
48+
else:
49+
if new_word in word_set:
50+
next_level.add(new_word)
51+
add_path(word, new_word, is_forward, path_dic)
52+
return done or bfs(next_level, end_level, is_forward, word_set, path_dic)
53+
54+
def add_path(word, new_word, is_forward, path_dic):
55+
if is_forward:
56+
path_dic[word] = path_dic.get(word, []) + [new_word]
57+
else:
58+
path_dic[new_word] = path_dic.get(new_word, []) + [word]
59+
60+
def construct_path(word, end_word, path_dic, path, paths):
61+
if word == end_word:
62+
paths.append(path)
63+
return
64+
if word in path_dic:
65+
for item in path_dic[word]:
66+
construct_path(item, end_word, path_dic, path + [item], paths)
67+
68+
front_level, end_level = {beginWord}, {endWord}
69+
path_dic = {}
70+
bfs(front_level, end_level, True, wordlist, path_dic)
71+
path, paths = [beginWord], []
72+
construct_path(beginWord, endWord, path_dic, path, paths)
73+
return paths
74+
75+
76+
if __name__ == "__main__":
77+
assert Solution().findLadders("hit", "cog", {"hot", "dot", "dog", "lot", "log"}) == [
78+
["hit", "hot", "dot", "dog", "cog"],
79+
["hit", "hot", "lot", "log", "cog"]
80+
]

137 Single Number II.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'''
2+
Given an array of integers, every element appears three times except for one. Find that single one.
3+
4+
Note:
5+
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
6+
'''
7+
8+
class Solution(object):
9+
def singleNumber(self, nums):
10+
"""
11+
:type nums: List[int]
12+
:rtype: int
13+
"""
14+
one, two, three = 0, 0, 0
15+
for num in nums:
16+
# calculate the count of the each bit
17+
three = two & num
18+
two = two | one & num
19+
one = one | num
20+
# clear the count for the bit which has achieved three
21+
one = one & ~three
22+
two = two & ~three
23+
return one
24+
25+
def singleNumber_normal(self, nums):
26+
result = 0
27+
for i in range(32):
28+
count = 0
29+
for num in nums:
30+
count += (num >> i) & 1
31+
rem = count % 3
32+
# deal with the negative situation
33+
if i == 31 and rem:
34+
result -= 1 << 31
35+
else:
36+
result |= rem << i
37+
return result
38+
39+
40+
if __name__ == "__main__":
41+
assert Solution().singleNumber([1, 1, 1, 2, 3, 3, 3]) == 2
42+
assert Solution().singleNumber([-2, -2, 1, 1, -3, 1, -3, -3, -4, -2]) == -4
43+
assert Solution().singleNumber_normal([1, 1, 1, 2, 3, 3, 3]) == 2
44+
assert Solution().singleNumber_normal([-2, -2, 1, 1, -3, 1, -3, -3, -4, -2]) == -4

0 commit comments

Comments
 (0)