Skip to content

Commit 5dda17b

Browse files
committed
no message
1 parent 803fb76 commit 5dda17b

23 files changed

+558
-9
lines changed

problems/backspace-string-compare.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,24 @@ def backspaceCompare(self, s1, s2):
8282
j -= 1
8383

8484
return True
85-
85+
86+
87+
class Solution(object):
88+
def backspaceCompare(self, s, t):
89+
def helper(S):
90+
ans = ''
91+
i = len(S)-1
92+
backspaceCount = 0
93+
94+
while i>=0:
95+
if S[i]=='#':
96+
backspaceCount += 1
97+
else:
98+
if backspaceCount>0:
99+
backspaceCount -= 1
100+
else:
101+
ans += S[i]
102+
i -= 1
103+
return ans
104+
105+
return helper(s)==helper(t)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
Imagine a list of sorted nodes, if we wanted to use the nodes to form a balanced BST, which root should we use?
3+
Yes, the one in the middle, since it can evenly spread two groups of nodes. This is what `getRoot()` does.
4+
And we do the same for the left half and right half. And so on. And so on...
5+
6+
Time: O(N), N is the number of nodes.
7+
Space: O(N)
8+
"""
9+
class Solution(object):
10+
def balanceBST(self, root):
11+
def getInorderNodes(root):
12+
nodes = []
13+
stack = []
14+
node = root
15+
16+
while node or stack:
17+
while node:
18+
stack.append(node)
19+
node = node.left
20+
21+
node = stack.pop()
22+
nodes.append(node)
23+
node = node.right
24+
25+
return nodes
26+
27+
def getRoot(l, r):
28+
if l>r: return None
29+
m = (l+r)/2
30+
root = inorderNodes[m]
31+
root.left = getRoot(l, m-1)
32+
root.right = getRoot(m+1, r)
33+
return root
34+
35+
inorderNodes = getInorderNodes(root)
36+
return getRoot(0, len(inorderNodes)-1)

problems/binary-search-tree-iterator.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,28 @@ def inOrderTraverse(root):
6161
#do something
6262
print node.val
6363

64-
node = node.right
64+
node = node.right
65+
66+
67+
68+
class BSTIterator(object):
69+
70+
def __init__(self, root):
71+
self.stack = []
72+
self.node = root
73+
74+
75+
76+
def next(self):
77+
while self.node:
78+
self.stack.append(self.node)
79+
self.node = self.node.left
80+
self.node = self.stack.pop()
81+
returnVal = self.node.val
82+
self.node = self.node.right
83+
return returnVal
84+
85+
86+
87+
def hasNext(self):
88+
return self.node or self.stack

problems/binary-tree-vertical-order-traversal.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,27 @@ def verticalOrder(self, root):
2424
if node.left: q.append((node.left, x-1))
2525
if node.right: q.append((node.right, x+1))
2626

27-
return [ans[x] for x in xrange(minX, maxX+1)]
27+
return [ans[x] for x in xrange(minX, maxX+1)]
28+
29+
30+
class Solution(object):
31+
def verticalOrder(self, root):
32+
if not root: return []
33+
ans = []
34+
minX = float('inf')
35+
maxX = float('-inf')
36+
locations = collections.defaultdict(list)
37+
q = collections.deque([(root, 0)])
38+
39+
while q:
40+
node, x = q.popleft()
41+
locations[x].append(node.val)
42+
minX = min(minX, x)
43+
maxX = max(maxX, x)
44+
if node.left: q.append((node.left, x-1))
45+
if node.right: q.append((node.right, x+1))
46+
47+
for x in xrange(minX, maxX+1):
48+
if locations[x]: ans.append(locations[x])
49+
50+
return ans

problems/convert-binary-search-tree-to-sorted-doubly-linked-list.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,6 @@ def inOrderTraverse(root):
101101
#do something
102102
print node.val
103103

104-
node = node.right
104+
node = node.right
105+
106+

problems/copy-list-with-random-pointer.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,38 @@ def copyRandomList(self, head):
5555

5656
"""
5757
Time: O(N). Two iteration. First iteration make a the clones. Second iteration setup the links.
58-
Space: O(1). No extra space except the cloned node.
59-
"""
58+
Space: O(N).
59+
"""
60+
61+
62+
"""
63+
Time: O(N)
64+
Space: O(1)
65+
"""
66+
class Solution(object):
67+
def copyRandomList(self, head):
68+
if not head: return head
69+
curr = head
70+
while curr:
71+
nextCurr = curr.next
72+
copy = Node(curr.val)
73+
curr.next = copy
74+
copy.next = nextCurr
75+
curr = nextCurr
76+
77+
copyHead = head.next
78+
79+
curr = head
80+
while curr:
81+
if curr.random: curr.next.random = curr.random.next
82+
curr = curr.next.next
83+
84+
curr = head
85+
while curr:
86+
nextCurr = curr.next.next
87+
if nextCurr:
88+
curr.next.next = nextCurr.next
89+
curr.next = nextCurr
90+
curr = nextCurr
91+
92+
return copyHead

problems/diameter-of-binary-tree.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,23 @@ def getMaxDepth(node):
8383

8484
# return ans
8585

86+
87+
"""
88+
For each route in the binary tree, we can view it from the highest node in the route.
89+
So the length will be helper(node.left) + 1 + helper(node.right).
90+
"""
91+
class Solution(object):
92+
def __init__(self):
93+
self.ans = 0 #number of nodes in the longest route
94+
95+
def diameterOfBinaryTree(self, root):
96+
#return the longest length to the leaf including itself
97+
#also update self.ans
98+
def helper(node):
99+
r = helper(node.right) if node.right else 0
100+
l = helper(node.left) if node.left else 0
101+
self.ans = max(self.ans, l+1+r)
102+
return max(l+1, r+1)
103+
104+
helper(root)
105+
return self.ans-1
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution(object):
2+
def __init__(self):
3+
self.lca = None
4+
self.pHeight = 0
5+
self.qHeight = 0
6+
7+
def findDistance(self, root, p, q):
8+
#find the count of p or q in node's subtree, set the first node we found that has count>=2 as lca.
9+
def findCount(node):
10+
if not node: return 0
11+
count = 0
12+
if node.val==p or node.val==q: count += 1
13+
count += findPQCount(node.left)
14+
count += findPQCount(node.right)
15+
if count>=2 and not self.lca: self.lca = node
16+
return count
17+
18+
def findHeight(node, h):
19+
if not node: return
20+
if node.val==p: self.pHeight = h
21+
if node.val==q: self.qHeight = h
22+
if self.pHeight and self.qHeight: return
23+
findHeight(node.left, h+1)
24+
findHeight(node.right, h+1)
25+
26+
findCount(root)
27+
findHeight(self.lca, 0)
28+
return self.qHeight + self.pHeight

problems/find-duplicate-subtrees.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution(object):
2+
def findDuplicateSubtrees(self, root):
3+
def dfs(node):
4+
if not node: return '#'
5+
string = str(node.val) + ',' + dfs(node.left) + ',' + dfs(node.right)
6+
data[string].append(node)
7+
return string
8+
9+
data = collections.defaultdict(list)
10+
ans = []
11+
12+
dfs(root)
13+
14+
for s in data:
15+
if len(data[s])>=2: ans.append(data[s][0])
16+
return ans

problems/find-k-closest-elements.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution(object):
2+
def findClosestElements(self, arr, K, X):
3+
def isCloserThan(n1, n2, x):
4+
return abs(x-n1)<abs(x-n2) or (abs(x-n1)==abs(x-n2) and n1<n2)
5+
6+
output1 = []
7+
output2 = []
8+
9+
r = bisect.bisect_left(arr, X)
10+
l = r-1
11+
12+
while len(output1)+len(output2)<K:
13+
if r>=len(arr) or (l>=0 and isCloserThan(arr[l], arr[r], X)):
14+
output1.append(arr[l])
15+
l -= 1
16+
else:
17+
output2.append(arr[r])
18+
r += 1
19+
20+
return output1[::-1]+output2

0 commit comments

Comments
 (0)