Skip to content

Commit 333870e

Browse files
committed
initial commit
1 parent 23c84f2 commit 333870e

File tree

105 files changed

+7098
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+7098
-2
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
.xlsx
3+
*.*~
4+
_*_.*
5+

3sum.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env python
2+
3+
4+
from __future__ import division
5+
import random
6+
7+
8+
'''
9+
Leetcode: 3Sum
10+
11+
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
12+
13+
Note:
14+
Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ? b ? c)
15+
The solution set must not contain duplicate triplets.
16+
For example, given array S = {-1 0 1 2 -1 -4},
17+
A solution set is:
18+
(-1, 0, 1)
19+
(-1, -1, 2)
20+
http://leetcode.com/2010/04/finding-all-unique-triplets-that-sums.html
21+
'''
22+
# ~ O(n^2)
23+
def three_sum(s):
24+
s = sorted(s) # O(nlogn)
25+
output = set()
26+
for k in range(len(s)):
27+
target = -s[k]
28+
i,j = k+1, len(s)-1
29+
while i < j:
30+
sum_two = s[i] + s[j]
31+
if sum_two < target:
32+
i += 1
33+
elif sum_two > target:
34+
j -= 1
35+
else:
36+
output.add((s[k],s[i],s[j]))
37+
i += 1
38+
j -= 1
39+
return output
40+
41+
42+
'''
43+
Leetcode: Two sum
44+
Given an array of integers, find two numbers such that they add up to a specific target number.
45+
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
46+
You may assume that each input would have exactly one solution.
47+
Input: numbers={2, 7, 11, 15}, target=9
48+
Output: index1=1, index2=2
49+
'''
50+
def two_sum(L, target):
51+
L = sorted(L)
52+
i = 0; j = len(L)-1
53+
while i < j:
54+
if L[i]+L[j] == target:
55+
return i+1, j+1
56+
elif L[i]+L[j] > target:
57+
j -= 1
58+
else:
59+
i += 1
60+
return -1,-1
61+
62+
63+
# O(n^(k-1))
64+
def k_sum(s, k, target):
65+
s = sorted(s) # O(nlogn)
66+
if k == 0:
67+
yield []
68+
69+
elif k == 1:
70+
if target in set(s): yield [target]
71+
72+
elif k == 2:
73+
i = 0; j = len(s)-1
74+
while i < j:
75+
sum_two = s[i] + s[j]
76+
if sum_two < target: i += 1
77+
elif sum_two > target: j -= 1
78+
else:
79+
yield [s[i], s[j]]
80+
i += 1
81+
j -= 1
82+
else:
83+
for i in range(len(s)):
84+
next_target = target - s[i]
85+
for p in k_sum(s[i+1:], k-1, next_target):
86+
yield [s[i]] + p
87+
88+
89+
if __name__ == '__main__':
90+
#print three_sum([-1, 0, 1, 2, -1, -4])
91+
#for p in k_sum([1, 0, -1, 0, -2, 2, 3, 5, -3], 4, 0): print p
92+
print two_sum([2, 7, 11, 15, 3], 13)

3sum_closest.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python
2+
'''
3+
Leetcode: 3Sum Closest
4+
5+
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
6+
7+
For example, given array S = {-1 2 1 -4}, and target = 1.
8+
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
9+
10+
'''
11+
from __future__ import division
12+
import random
13+
14+
### DP? Given a list L
15+
# S(i, k, target) = True if we can find k elements among L[:i] to sum up to target
16+
# S(i, k, target) = S(i-1, k-1, target-L[i-1]) or S(i-1, k, target)
17+
def sum_closest(L, num_k, target):
18+
import math
19+
n = len(L)
20+
S = {}
21+
prev = {}
22+
max_t = sum([x for x in L if x > 0])
23+
min_t = sum([x for x in L if x <= 0])
24+
print 'target range: [%d, %d]' %(min_t, max_t)
25+
26+
# Initialization:
27+
# S(0,any,any) = False
28+
# S(any,0,any) = False
29+
# S(any,0,0) = True
30+
for i in range(n+1):
31+
for t in range(min_t, max_t+1):
32+
S[(i,0,t)] = False
33+
for k in range(num_k+1):
34+
for t in range(min_t, max_t+1):
35+
S[(0,k,t)] = False
36+
for i in range(n+1):
37+
S[(i,0,0)] = True
38+
39+
for i in range(1,n+1):
40+
for k in range(1,num_k+1):
41+
for t in range(min_t, max_t+1):
42+
with_elem = S[(i-1,k-1,t-L[i-1])] if min_t <= t-L[i-1] <= max_t else False
43+
without_elem = S[(i-1,k,t)]
44+
45+
S[(i,k,t)] = with_elem or without_elem
46+
if with_elem: prev[(i,k,t)] = (i-1,k-1,t-L[i-1])
47+
elif without_elem: prev[(i,k,t)] = (i-1,k,t)
48+
49+
# min{|t-target| for S[(n,num_k,t)] == True}
50+
cands = [t for t in range(min_t, max_t+1) if S[(n,num_k,t)]]
51+
output_t = min(cands, key=lambda x:math.fabs(x-target))
52+
53+
# print out
54+
output = []
55+
i,k,t = n,num_k,output_t
56+
while (i,k,t) in prev:
57+
next_i,next_k,next_t = prev[(i,k,t)]
58+
if next_k == k-1: output.append(L[next_i])
59+
i,k,t = next_i,next_k,next_t
60+
print 'output:', output, 'sum(output):', sum(output)
61+
return output
62+
63+
64+
if __name__ == '__main__':
65+
sum_closest([-1, 2, 1, -3, 6], 2, 2)
66+
67+

BinaryTree.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env python
2+
3+
from __future__ import division
4+
from math import log10
5+
6+
class Node(object):
7+
def __init__(self, value=0,
8+
left=None, right=None,
9+
id=None, parent=None):
10+
self.id = id
11+
self.left = left
12+
self.right = right
13+
self.value = value
14+
self.parent = parent
15+
16+
def __str__(self):
17+
if self.left is None and self.right is None:
18+
return str(self.value)
19+
else:
20+
return '%s (%s, %s)' % (
21+
str(self.value),
22+
str(self.left),
23+
str(self.right))
24+
25+
def __repr__(self):
26+
s = 'TreeNode Object (id=' + str(self.id) + \
27+
' value='+str(self.value)+')'
28+
return s
29+
30+
def pretty_print(self):
31+
# get each levels
32+
level = [self]
33+
to_prints = [[self.value]]
34+
while True:
35+
is_all_none = True
36+
next_level = []
37+
to_print = []
38+
for n in level:
39+
if n is None:
40+
next_level += [None, None]
41+
to_print += ['#','#']
42+
else:
43+
is_all_none = False
44+
next_level += [n.left, n.right]
45+
left_val = n.left.value if n.left and n.left.value else '#'
46+
right_val = n.right.value if n.right and n.right.value else '#'
47+
to_print += [left_val, right_val]
48+
if is_all_none: break
49+
level = next_level
50+
to_prints.append(to_print)
51+
52+
#max_val_digits = max([max([len(str(v)) for v in r]) for r in to_prints])
53+
#print max_val_digits
54+
55+
to_prints = to_prints[:-1] # remove the last row with only '#'
56+
to_pretty_prints = []
57+
to_prints.reverse()
58+
for i, row in enumerate(to_prints):
59+
row = map(str,row)
60+
#row = [' '*(max_val_digits-len(v))+v for v in row]
61+
sep = ' '*(2**(i+1) - 1)
62+
space = ' '*(2**i - 1)
63+
to_pretty_prints.insert(0, space + sep.join(row) + space)
64+
print '\n'.join(to_pretty_prints)
65+
66+
67+
root = Node(value=5,
68+
left=Node(value=4,
69+
left=Node(value=1,
70+
right=Node(value=2))
71+
),
72+
right=Node(value=8,
73+
left=Node(value=3),
74+
right=Node(value=4,
75+
left=Node(value=9),
76+
right=Node(value=1))
77+
)
78+
)
79+
80+
BST = Node(value=5,
81+
left=Node(value=2,
82+
left=Node(value=1,
83+
right=Node(value=1.5,
84+
left=Node(value=1.2))),
85+
right=Node(value=3)
86+
),
87+
right=Node(value=9,
88+
left=Node(value=7),
89+
right=Node(value=15,
90+
right=Node(value=16)
91+
)
92+
)
93+
)
94+
95+
root_with_id = Node(id=0,value=-3,
96+
left=Node(id=1,value=-2,
97+
left=Node(id=3,value=3,
98+
left=Node(id=7,value=1,
99+
left=Node(id=11,value=4)),
100+
right=Node(id=8,value=1)),
101+
right=Node(id=4,value=-1,
102+
left=Node(id=9,value=4),
103+
right=Node(id=10,value=2))
104+
),
105+
right=Node(id=2,value=2,
106+
left=Node(id=5,value=-1),
107+
right=Node(id=6,value=3,
108+
right=Node(id=12,value=2))
109+
)
110+
)
111+
112+
113+
if __name__ == '__main__':
114+
root.pretty_print()
115+
print
116+
BST.pretty_print()

LCA.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env python
2+
'''
3+
Leetcode: Lowest common ancesters
4+
http://leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-search-tree.html
5+
http://leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-tree-part-i.html
6+
http://leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-tree-part-ii.html
7+
'''
8+
from __future__ import division
9+
import random
10+
from BinaryTree import Node, BST, root
11+
12+
13+
### We traverse from the bottom, and once we reach a node which matches one of the two nodes, we pass it up to its parent. The parent would then test its left and right subtree if each contain one of the two nodes. If yes, then the parent must be the LCA and we pass its parent up to the root. If not, we pass the lower node which contains either one of the two nodes (if the left or right subtree contains either p or q), or NULL (if both the left and right subtree does not contain either p or q) up.
14+
# O(n)
15+
def lca(root, a, b):
16+
if not root: return None
17+
if root.value == a or root.value == b: return root
18+
left = lca(root.left, a, b)
19+
right = lca(root.right, a, b)
20+
if left and right: # if p and q are on both sides
21+
return root
22+
else: # either a/b is on one side OR a/b is not in L&R subtrees
23+
return left if left else right
24+
25+
26+
### With parent pointer
27+
# find the height h(a), h(b)
28+
# move the lower node b up by h(a)-h(b) steps
29+
# move a and b up together until a=b
30+
def lca_parent(root, node_a, node_b):
31+
h_a = find_height(root, node_a)
32+
h_b = find_height(root, node_b)
33+
if h_b > h_a:
34+
node_a, node_b = node_b, node_a
35+
h_a,h_b = h_b,h_a
36+
for _ in range(h_b - h_a):
37+
node_b = node_b.parent
38+
while node_a != node_b:
39+
node_a = node_a.parent
40+
node_b = node_b.parent
41+
return node_a
42+
43+
def find_height(root, node):
44+
h = 0
45+
while node:
46+
node = node.parent
47+
h += 1
48+
return h
49+
50+
51+
# 1. Both nodes are to the left of the tree.
52+
# 2. Both nodes are to the right of the tree.
53+
# 3. One node is on the left while the other is on the right.
54+
# 4. When the current node equals to either of the two nodes, this node must be the LCA too.
55+
# O(logn)
56+
def lca_BST(root, a, b):
57+
while root:
58+
if a <= root.value <= b:
59+
return root
60+
elif min(a,b) < root.value:
61+
root = root.left
62+
elif max(a,b) > root.value:
63+
root = root.right
64+
return None
65+
66+
67+
if __name__ == '__main__':
68+
print lca_BST(BST, 1,3)
69+
print lca_BST(BST, 9,16)
70+
71+

LinkedList.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env python
2+
3+
from __future__ import division
4+
5+
class Node(object):
6+
def __init__(self, value, next=None, prev=None):
7+
self.prev = prev
8+
self.next = next
9+
self.value = value
10+
11+
def __str__(self):
12+
if self.next is None:
13+
return str(self.value)
14+
else:
15+
return '%d (%s)' % (self.value, str(self.next))
16+
17+
def __repr__(self):
18+
s = 'LinkedListNode Object (value='+str(self.value)+')'
19+
return s
20+
21+

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
LeetcodePython
1+
Leetcode Practice in Python
22
==============
3+
This repository includes answers to Leetcode coding interview questions.
4+
5+
ALl the problems please refer to http://oj.leetcode.com/problems/
6+
7+
The problem descriptions are also included in each python file.
8+
39

4-
Leetcode Practice in Python

0 commit comments

Comments
 (0)