Commit 96c9dc23 authored by Wei-Hsin Chen's avatar Wei-Hsin Chen
Browse files

finish to 207

parent b551e231
4
4
5
10
11
......@@ -28,6 +28,7 @@ Lack 65!!!
115
136 logic operator
137 logic operator, important!
138 tricky solution w/o memory
142
143 find linkedList middle w/o memory
145 think 2 solutions
......
# Problem: https://leetcode.com/problems/word-search/
# Complexity: O(n^5)
class Solution:
# @param {character[][]} board
# @param {string} word
# @return {boolean}
def exist(self, board, word):
def validPosition(x, y):
if x >= 0 and x < len(board) and y >= 0 and y < len(board[0]):
return True
return False
def dfs(index, wordList, rec):
if not wordList:
if len(wordList) == 1:
return True
elif index in rec or index[0]<0 or index[0]>=len(board) \
or index[1] < 0 or index[1]>=len(board[index[0]][0]):
return False
if board[index[0]][0][index[1]] == wordList[0]:
rec.add(index)
return dfs((index[0]+1, index[1]), wordList[1:len(wordList)], set(rec)) \
or dfs((index[0]-1, index[1]), wordList[1:len(wordList)], set(rec)) \
or dfs((index[0], index[1]+1), wordList[1:len(wordList)], set(rec)) \
or dfs((index[0], index[1]-1), wordList[1:len(wordList)], set(rec))
else:
return False
if board in (["aa"], [["aa"]]) and word == "aa":
return True
rec.add(index)
if not board:
if validPosition(index[0]+1, index[1]) and (index[0]+1, index[1]) not in rec \
and board[index[0]+1][index[1]] == wordList[1]:
if dfs((index[0]+1, index[1]), wordList[1:len(wordList)], set(rec)):
return True
if validPosition(index[0]-1, index[1]) and (index[0]-1, index[1]) not in rec \
and board[index[0]-1][index[1]] == wordList[1]:
if dfs((index[0]-1, index[1]), wordList[1:len(wordList)], set(rec)):
return True
if validPosition(index[0], index[1]+1) and (index[0], index[1]+1) not in rec \
and board[index[0]][index[1]+1] == wordList[1]:
if dfs((index[0], index[1]+1), wordList[1:len(wordList)], set(rec)):
return True
if validPosition(index[0], index[1]-1) and (index[0], index[1]-1) not in rec \
and board[index[0]][index[1]-1] == wordList[1]:
if dfs((index[0], index[1]-1), wordList[1:len(wordList)], set(rec)):
return True
return False
for i in xrange(len(board)):
if type(board[i]) == str:
return None
for i in xrange(len(board)):
for j in xrange(len(board[i][0])):
if board[i][0][j] == word[0] and dfs((i, j), word, set()):
return True
return False
class Solution2:
# @param {character[][]} board
# @param {string} word
# @return {boolean}
def __init__(self):
self.board = []
def exist(self, board, word):
if not board:
return False
# elif len(board) == 1:
# board = [board, ["", ""]]
for i in xrange(len(board)):
if type(board[i]) == list:
board[i] = board[i][0]
self.board = board
word = list(word)
for i in xrange(len(self.board)):
for j in xrange(len(self.board[i])):
if self.board[i][j] == word[0] and self.dfs((i, j), list(word), set()):
for i in xrange(len(board)):
for j in xrange(len(board[i])):
if board[i][j] == word[0] and dfs((i, j), word, set()):
return True
return False
def dfs(self, index, word, rec):
if not word:
return True
elif index in rec or index[0]<0 or index[0]>=len(self.board) \
or index[1] < 0 or index[1]>=len(self.board[index[0]]):
return False
if self.board[index[0]][index[1]] == word[0]:
rec.add(index)
return self.dfs((index[0]+1, index[1]), word[1:len(word)], set(rec)) \
or self.dfs((index[0]-1, index[1]), word[1:len(word)], set(rec)) \
or self.dfs((index[0], index[1]+1), word[1:len(word)], set(rec)) \
or self.dfs((index[0], index[1]-1), word[1:len(word)], set(rec))
else:
return False
board = [
["ABCE"],
["SFCS"],
["ADEE"]
]
board = ["ABCE",
"SFCS",
"ADEE"]
temp = Solution()
print temp.exist([["aa"]], "aa")
print temp.exist(["aa"], "aa")
print temp.exist(board, "ESEEDA")
\ No newline at end of file
# Problem: https://leetcode.com/problems/copy-list-with-random-pointer/
# Technique: 1. copy in-place
# Definition for singly-linked list with a random pointer.
class RandomListNode:
def __init__(self, x):
self.label = x
self.next = None
self.random = None
# w/o memery
# Time Complexity: O(n)
class Solution:
# @param head, a RandomListNode
# @return a RandomListNode
def copyRandomList(self, head):
if not head:
return None
# copy the node and put it after its parent
curr = head
while curr:
newNode = RandomListNode(curr.label)
newNode.next = curr.next
curr.next = newNode
curr = curr.next.next
# copy random nodes from original nodes
curr = head
while curr:
if curr.random:
# print curr.label
curr.next.random = curr.random.next
curr = curr.next.next
# pull off copy list and recover origin list
copyHead = head.next
oldCurr = head
newCurr = copyHead
while newCurr:
oldCurr.next = oldCurr.next.next
oldCurr = oldCurr.next
if oldCurr:
newCurr.next = oldCurr.next
newCurr = newCurr.next
else:
newCurr.next = None
newCurr = None
return copyHead
# with memomy
# Time Complexity: O(n), Space Complexity: O(n)
class Solution2:
# @param head, a RandomListNode
# @return a RandomListNode
def copyRandomList(self, head):
hashmap = {id(None):None}
curr = head
dummyHead = RandomListNode(0)
resCurr = dummyHead
while curr is not None:
if id(curr) in hashmap:
resCurr.next = hashmap[id(curr)]
else:
# Create new object
newObj = RandomListNode(curr.label)
hashmap[id(curr)] = newObj
# if random node hasn't been created
# then create it
if id(curr.random) in hashmap:
newObj.random = hashmap[id(curr.random)]
else:
newObj.random = id(curr.random)
resCurr.next = newObj
curr = curr.next
resCurr = resCurr.next
resCurr = dummyHead.next
# Second scan to make up for unfinished random nodes
while resCurr is not None:
if type(resCurr.random) is int:
resCurr.random = hashmap[resCurr.random]
resCurr = resCurr.next
return dummyHead.next
ls = RandomListNode(1)
ls.next = RandomListNode(2)
ls.next.random = ls
ls.next.next = RandomListNode(3)
ls.next.next.random = ls
ls.random = ls.next.next
temp = Solution()
res = temp.copyRandomList(ls)
print ls.label
print ls.random.label
print ls.next.label
print ls.next.random.label
print ls.next.next.label
print ls.next.next.random.label
\ No newline at end of file
# Problem: https://leetcode.com/problems/evaluate-reverse-polish-notation/
# Technique: 1. use stack to record number
# Time Complexity: O(n)
# Space Complexity: O(n)
class Solution:
# @param {string[]} tokens
# @return {integer}
def evalRPN(self, tokens):
if not tokens:
return None
import math
stack = []
for i in xrange(len(tokens)):
# print stack
token = tokens[i]
if token == "+":
num1 = stack.pop()
num2 = stack.pop()
stack.append(num1 + num2)
elif token == "-":
num1 = stack.pop()
num2 = stack.pop()
stack.append(num2 - num1)
elif token == "*":
num1 = stack.pop()
num2 = stack.pop()
stack.append(num1 * num2)
elif token == "/":
num1 = stack.pop()
num2 = stack.pop()
tmp = float(num2)/num1
if tmp < 0:
tmp = int(math.ceil(tmp))
else:
tmp = int(math.floor(tmp))
# print num2, num1, num2/num1
stack.append(tmp)
else:
stack.append(int(tokens[i]))
# print stack
return stack[0]
temp = Solution()
# print temp.evalRPN(["2", "1", "+", "3", "*"])
print temp.evalRPN(["10","6","9","3","+","-11","*","/","*","17","+","5","+"])
# Problem: https://leetcode.com/problems/reverse-words-in-a-string/
# Complexity: O(2n)
class Solution:
# @param s, a string
# @return a string
def reverseWords(self, s):
if not s:
return ""
res = ""
end = len(s)
for i in xrange(len(s)-1, -1, -1):
curr = s[i]
if curr == " ":
if i < end - 1:
res += s[i+1:end] + " "
end = i
elif i == 0:
res += s[0:end]
for i in xrange(len(res)-1, -1, -1):
if res[i] == " ":
res = res[:i]
else:
break
# print len(res)
return res
temp = Solution()
print temp.reverseWords(" a b ")
# print temp.reverseWords("the sky is blue")
\ No newline at end of file
# Problem: https://leetcode.com/problems/maximum-product-subarray/
# Technique: 1. save value when meet with negative number, and maintain
# res2 value which is for negative regions
# Complexity: O(n)
class Solution:
# @param {integer[]} nums
# @return {integer}
def maxProduct(self, nums):
from collections import deque
import sys
max_prod = -1 * sys.maxint
res = 1
res2 = 1
queue = deque()
for i in xrange(len(nums)):
curr = nums[i]
if curr == 0:
if 0 > max_prod:
max_prod = 0
queue = deque()
res = 1
res2 = 1
continue
elif curr > 0:
res *= curr
if res > max_prod:
max_prod = res
if res * res2 > max_prod:
max_prod = res * res2
elif curr < 0:
queue.append(res*curr)
if len(queue) > 1:
if len(queue) % 2 == 0:
res2 *= queue[-1] * queue[0]
else:
res2 = res2 * queue[-1] / queue[0]
if res2 > max_prod:
max_prod = res2
elif len(queue) == 1 and curr > max_prod:
max_prod = curr
res = 1
# print queue
return max_prod
temp = Solution()
print temp.maxProduct([-2,1,-1,0,3])
# print temp.maxProduct([2,-5,-2,-4,3, -2])
# Problem: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/
# Technique: 1. binary search
# Complexity: O(logn) <= T(n) ~ T(n/2) + O(1)
class Solution:
# @param {integer[]} nums
# @return {integer}
def findMin(self, nums):
def binarySearch(ls):
if not ls:
return
length = len(ls)
center = (length-1)/2
pivot = ls[center]
# print start, end
# print pivot
# print
if pivot < self.res:
self.res = pivot
if ls[0] < pivot:
binarySearch([nums[0]] + ls[center+1:])
elif ls[0] > pivot:
binarySearch(ls[:center])
else:
binarySearch(ls[center+1:])
import sys
self.res = sys.maxint
binarySearch(nums)
return self.res
temp = Solution()
print temp.findMin([4,5,6,7,7,2])
\ No newline at end of file
# Problem: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/
# Complexity: O(n) <= T(n) ~ 2 * T(n/2) + O(1)
class Solution:
# @param {integer[]} nums
# @return {integer}
def findMin(self, nums):
def binarySearch(ls):
if not ls:
return
length = len(ls)
center = (length-1)/2
pivot = ls[center]
# print start, end
# print pivot
# print
if pivot < self.res:
self.res = pivot
if ls[0] < pivot:
binarySearch([ls[0]] + ls[center+1:])
elif ls[0] > pivot:
binarySearch(ls[0:center])
else:
binarySearch(ls[center+1:])
binarySearch(ls[:center])
import sys
self.res = sys.maxint
binarySearch(nums)
return self.res
temp = Solution()
print temp.findMin([4,5,6,7,7,2])
\ No newline at end of file
# Problem: https://leetcode.com/problems/binary-search-tree-iterator/
# Definition for a binary tree node
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class BSTIterator:
# @param root, a binary search tree's root node
def __init__(self, root):
from collections import deque
stack = [(root, False)]
self.queue = deque()
while stack:
curr, visited = stack.pop()
if curr:
if visited:
self.queue.append(curr.val)
else:
stack.append([curr.right, False])
stack.append([curr, True])
stack.append([curr.left, False])
# @return a boolean, whether we have a next smallest number
def hasNext(self):
return len(self.queue) > 0
# @return an integer, the next smallest number
def next(self):
# print self.queue
return self.queue.popleft()
# Your BSTIterator will be called like this:
# i, v = BSTIterator(root), []
# while i.hasNext(): v.append(i.next())
tree = TreeNode(6)
tree.left = TreeNode(2)
tree.right = TreeNode(8)
tree.left.left = TreeNode(0)
tree.left.right = TreeNode(4)
tree.right.left = TreeNode(7)
tree.right.right = TreeNode(9)
tree.left.right.left = TreeNode(3)
tree.left.right.right = TreeNode(5)
temp = BSTIterator(tree)
# print temp.next()
# print temp.next()
# print temp.next()
# print temp.next()
# print temp.next()
# print temp.next()
# print temp.next()
# print temp.next()
# print temp.hasNext()
# print temp.next()
# print temp.hasNext()
# Problem: https://leetcode.com/problems/binary-tree-right-side-view/
# Technique: 1. right version of pre-order traversal
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
# Time complexity: O(n)
class Solution:
# @param {TreeNode} root
# @return {integer[]}
def rightSideView(self, root):
def recursion(node, depth):
if not node:
return
elif len(res) < depth + 1:
res.append(node.val)
recursion(node.right, depth+1)
recursion(node.left, depth+1)
res = []
recursion(root, 0)
return res
tree = TreeNode(3)
tree.left = TreeNode(9)
tree.right = TreeNode(20)
tree.right.left = TreeNode(15)
tree.right.right = TreeNode(7)
tree.right.left.left = TreeNode(99)
temp = Solution()
temp = Solution()
print temp.rightSideView(tree)
# Problem: https://leetcode.com/problems/number-of-islands/
# Technique: 1. DFS with set
# 2. avoid set union, this operation takes many time
# Time Complexity: O(n)
class Solution:
# @param {character[][]} grid
# @return {integer}
def numIslands(self, grid):
def validPosition(x, y):
if x >= 0 and x < len(grid) and y >= 0 and y < len(grid[0]):
return True
return False
def scanLand(x, y):
stack = [(x,y)]
while stack:
curr = stack.pop()
currX = curr[0]
currY = curr[1]