Squash commit

This commit is contained in:
Tay Yang Shun
2017-09-20 15:27:28 +08:00
commit 2182a70770
70 changed files with 5486 additions and 0 deletions

26
utilities/binarySearch.js Normal file
View File

@ -0,0 +1,26 @@
function binarySearch(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left < right) {
let mid = left + Math.floor((right - left) / 2);
if (arr[mid] === target) {
return mid;
}
if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}
console.log(binarySearch([1, 2, 3, 10], 1) === 0)
console.log(binarySearch([1, 2, 3, 10], 2) === 1)
console.log(binarySearch([1, 2, 3, 10], 3) === 2)
console.log(binarySearch([1, 2, 3, 10], 10) === 3)
console.log(binarySearch([1, 2, 3, 10], 9) === 3)
console.log(binarySearch([1, 2, 3, 10], 4) === 3)
console.log(binarySearch([1, 2, 3, 10], 0) === 0)
console.log(binarySearch([1, 2, 3, 10], 11) === 3)
console.log(binarySearch([5, 7, 8, 10], 3) === 0)

View File

@ -0,0 +1,22 @@
def binary_search(arr, target):
left = 0;
right = len(arr) - 1
while left < right:
mid = left + (right - left) / 2;
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
print(binary_search([1, 2, 3, 10], 1) == 0)
print(binary_search([1, 2, 3, 10], 2) == 1)
print(binary_search([1, 2, 3, 10], 3) == 2)
print(binary_search([1, 2, 3, 10], 10) == 3)
print(binary_search([1, 2, 3, 10], 9) == 3)
print(binary_search([1, 2, 3, 10], 4) == 3)
print(binary_search([1, 2, 3, 10], 0) == 0)
print(binary_search([1, 2, 3, 10], 11) == 3)
print(binary_search([5, 7, 8, 10], 3) == 0)

View File

@ -0,0 +1,19 @@
# For mapping a lowercase character to a prime number.
# Useful for checking whether two strings are anagram or permutations of each other.
primes = {
'a': 2, 'b': 3, 'c': 5, 'd': 7, 'e': 11, 'f': 13,
'g': 17, 'h': 19, 'i': 23, 'j': 29, 'k': 31, 'l': 37,
'm': 41, 'n': 43, 'o': 47, 'p': 53, 'q': 59, 'r': 61,
's': 67, 't': 71, 'u': 73, 'v': 79, 'w': 83, 'x': 89,
'y': 97, 'z': 101, ' ': 103,
}
import functools
def mul(seq):
return functools.reduce(lambda a, b: a * b, seq, 1)
def prime_value_of_string(string):
return mul([primes[c] for c in string])
print(prime_value_of_string('abcde'))

View File

@ -0,0 +1,35 @@
function graphTopoSort(numberNodes, edges) {
const nodes = new Map();
const order = [];
const queue = [];
for (let i = 0; i < numberNodes; i++) {
nodes.set(i, { in: 0, out: new Set() });
}
edges.forEach(edge => {
const [node_id, pre_id] = edge;
nodes.get(node_id).in += 1;
nodes.get(pre_id).out.add(node_id);
});
for (let [node_id, value] of nodes.entries()) {
if (value.in === 0) {
queue.push(node_id);
}
}
while (queue.length) {
const node_id = queue.shift();
for (let outgoing_id of nodes.get(node_id).out) {
nodes.get(outgoing_id).in -= 1;
if (nodes.get(outgoing_id).in === 0) {
queue.push(outgoing_id);
}
}
order.push(node_id);
}
return order.length == numberNodes ? order : [];
}
console.log(graphTopoSort(3, [[0, 1], [0, 2]]))

24
utilities/graph_dfs.py Normal file
View File

@ -0,0 +1,24 @@
def graph_dfs(matrix):
rows, cols = len(matrix), len(matrix[0])
visited = set()
directions = ((0, 1), (0, -1), (1, 0), (-1, 0))
def dfs(i, j):
if (i, j) in visited:
return
visited.add((i, j))
# Traverse neighbors.
for direction in directions:
next_i, next_j = i + direction[0], j + direction[1]
if 0 <= next_i < rows and 0 <= next_j < cols: # Check boundary.
# Add any other checking here ^
dfs(next_i, next_j)
for i in range(rows):
for j in range(cols):
dfs(i, j)
graph_dfs([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
])

View File

@ -0,0 +1 @@
# TODO

View File

@ -0,0 +1,21 @@
def graph_topo_sort(num_nodes, edges):
from collections import deque
nodes, order, queue = {}, [], deque()
for node_id in range(num_nodes):
nodes[node_id] = { 'in': 0, 'out': set() }
for node_id, pre_id in edges:
nodes[node_id]['in'] += 1
nodes[pre_id]['out'].add(node_id)
for node_id in nodes.keys():
if nodes[node_id]['in'] == 0:
queue.append(node_id)
while len(queue):
node_id = queue.pop()
for outgoing_id in nodes[node_id]['out']:
nodes[outgoing_id]['in'] -= 1
if nodes[outgoing_id]['in'] == 0:
queue.append(outgoing_id)
order.append(node_id)
return order if len(order) == num_nodes else []
print(graph_topo_sort(3, [[0, 1], [0, 2]]))

View File

@ -0,0 +1,19 @@
function isSubsequence(s, t) {
if (s.length > t.length) {
return false;
}
let matchedLength = 0;
for (let i = 0; i < t.length; i++) {
if (matchedLength < s.length && s[matchedLength] === t[i]) {
matchedLength += 1;
}
}
return matchedLength === s.length;
}
console.log(isSubsequence('abc', 'abcde') === true);
console.log(isSubsequence('abd', 'abcde') === true);
console.log(isSubsequence('abf', 'abcde') === false);
console.log(isSubsequence('abef', 'abcde') === false);
console.log(isSubsequence('abcdef', 'abcde') === false);
console.log(isSubsequence('a', 'abcde') === true);

View File

@ -0,0 +1,13 @@
def is_subsequence(s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
if len(s) > len(t):
return False
matched_s = 0
for char in t:
if matched_s < len(s) and s[matched_s] == char:
matched_s += 1
return matched_s == len(s)

View File

@ -0,0 +1 @@
# TODO

11
utilities/treeEqual.js Normal file
View File

@ -0,0 +1,11 @@
function treeEqual(node1, node2) {
if (!node1 && !node2) {
return true;
}
if (!node1 || !node2) {
return false;
}
return node1.val == node2.val &&
treeEqual(node1.left, node2.left) &&
treeEqual(node1.right, node2.right);
}

10
utilities/treeMirror.js Normal file
View File

@ -0,0 +1,10 @@
function treeMirror(node) {
if (!node) {
return;
}
let temp = node.left;
node.left = node.right;
node.right = temp;
treeMirror(node.left);
treeMirror(node.right);
}

8
utilities/tree_equal.py Normal file
View File

@ -0,0 +1,8 @@
def tree_equal(node1, node2):
if not node1 and not node2:
return True
if not node1 or not node2:
return False
return node1.val == node2.val and \
tree_equal(node1.left, node2.left) and \
tree_equal(node1.right, node2.right)

6
utilities/tree_mirror.py Normal file
View File

@ -0,0 +1,6 @@
def tree_mirror(node):
if not node:
return
node.left, node.right = node.right, node.left
tree_mirror(node.left)
tree_mirror(node.right)

View File

@ -0,0 +1,62 @@
# Various iterative ways of traversing a tree.
def inorder_traversal(root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
result = []
stack = [root]
while len(stack) > 0:
curr_node = stack.pop()
if curr_node.left:
stack.append(curr_node)
stack.append(curr_node.left)
curr_node.left = None
else:
result.append(curr_node.val)
if curr_node.right:
stack.append(curr_node.right)
return result
def preorder_traversal(root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
result = []
stack = [root]
while len(stack) > 0:
curr_node = stack.pop()
result.append(curr_node.val)
if curr_node.right:
stack.append(curr_node.right)
if curr_node.left:
stack.append(curr_node.left)
return result
def postorder_traversal(root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
result = []
stack = [root]
while len(stack) > 0:
curr_node = stack.pop()
if curr_node.left:
stack.append(curr_node)
stack.append(curr_node.left)
curr_node.left = None
elif curr_node.right:
stack.append(curr_node)
stack.append(curr_node.right)
curr_node.right = None
else:
result.append(curr_node.val)
return result

80
utilities/trie.py Normal file
View File

@ -0,0 +1,80 @@
class Trie(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.d = {}
def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: void
"""
curr = self.d
for char in word:
if char not in curr:
curr[char] = {}
curr = curr[char]
curr['#'] = {} # Using an empty dict rather than a boolean value makes recursive traversal easier.
def search(self, word):
"""
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
curr = self.d
for char in word:
if char in curr:
curr = curr[char]
else:
return False
return '#' in curr
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: bool
"""
curr = self.d
for char in prefix:
if char in curr:
curr = curr[char]
else:
return False
return True
def searchRegex(self, word):
"""
Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter.
:type word: str
:rtype: bool
"""
def traverse(node, index):
if len(word) == index:
return '#' in node
char = word[index]
if char == '.':
for key in node.keys():
if traverse(node[key], index+1):
return True
return False
else:
if char not in node:
return False
return traverse(node[char], index + 1)
return traverse(self.d, 0)
# Example
trie = Trie()
trie.insert('hello')
print(trie.search('hello') == True)
print(trie.startsWith('hello') == True)
print(trie.startsWith('hel') == True)
print(trie.search('world') == False)
print(trie.startsWith('wor') == False)
print(trie.searchRegex('..llo') == True)
print(trie.searchRegex('..llx') == False)
print(trie.searchRegex('..') == False)