Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/yueguo12/public_html/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340

Lucy's Blog http://yueguo1217.com DS & E Thu, 07 Feb 2019 22:36:46 +0000 en-US hourly 1 https://wordpress.org/?v=5.5.1 LeetCode : 155. Min Stack ( Easy 81 ) in Python http://yueguo1217.com/leetcode-155-min-stack-easy-81-in-python/ Thu, 03 Jan 2019 02:41:09 +0000 http://yueguo1217.com/?p=906 Problem

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

• push(x) — Push element x onto stack.
• pop() — Removes the element on top of the stack.
• top() — Get the top element.
• getMin() — Retrieve the minimum element in the stack.

Example:

```MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --&gt; Returns -3.
minStack.pop();
minStack.top();      --&gt; Returns 0.
minStack.getMin();   --&gt; Returns -2.```
]]>
LeetCode : 17. Letter Combinations of a Phone Number ( Median 56 ) in Python http://yueguo1217.com/leetcode-17-letter-combinations-of-a-phone-number-median-56-in-python/ http://yueguo1217.com/leetcode-17-letter-combinations-of-a-phone-number-median-56-in-python/#respond Thu, 21 Dec 2017 19:49:30 +0000 http://yueguo1217.com/?p=887 Problem

Given a digit string, return all possible letter combinations that the number could represent.

A mapping of digit to letters (just like on the telephone buttons) is given below. ```<b>Input:</b>Digit string "23"
<b>Output:</b> ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].```

Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.

###### Solution

```class Solution(object):
def letterCombinations(self, digits):
"""
:type digits: str
:rtype: List[str]
"""
theDict = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}
if digits == '':
return []
else:
l = [map(lambda y: y+x, theDict[digits]) for x in self.letterCombinations(digits[1:])] if len(digits) > 1 else [x for x in theDict[digits]]
return [item for sublist in l for item in sublist] # meaning(not syntax correct) [[item for item in sublist] for sublist in l]```

]]>
http://yueguo1217.com/leetcode-17-letter-combinations-of-a-phone-number-median-56-in-python/feed/ 0
TODO Algorithm Problems http://yueguo1217.com/todo-algorithm-problems/ http://yueguo1217.com/todo-algorithm-problems/#respond Fri, 15 Dec 2017 13:58:23 +0000 http://yueguo1217.com/?p=880
• 659. Split Array into Consecutive Subsequences – Nov 20
1. hint: how to deal with duplicates
• 51. N-Queens – Dec 16
1. Backtracking – Brute force
• 367. Valid Perfect Square – Oct 2, 2018
• To review

1. 680. Valid Palindrome II – Jan 28, 2019
2. 767. Reorganize String – Feb 8, 2019
• the heap solution
]]>
http://yueguo1217.com/todo-algorithm-problems/feed/ 0
LeetCode : 108. Convert Sorted Array to Binary Search Tree ( Easy 80 ) in Python http://yueguo1217.com/leetcode-108-convert-sorted-array-to-binary-search-tree-easy-80-in-python/ http://yueguo1217.com/leetcode-108-convert-sorted-array-to-binary-search-tree-easy-80-in-python/#respond Tue, 12 Dec 2017 19:02:08 +0000 http://yueguo1217.com/?p=876 Continue reading LeetCode : 108. Convert Sorted Array to Binary Search Tree ( Easy 80 ) in Python ]]> Problem

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

Example:

```Given the sorted array: [-10,-3,0,5,9],

One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:

0
/ \
-3   9
/   /
-10  5```

Notice: remember to initialize

method no need of a helper

```# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
def sortedArrayToBST(self, nums):
"""
:type nums: List[int]
:rtype: TreeNode
"""
# !!! the order of inserting matters=> balance or not
# use BS
# helper
def BSTinsertBalanced(root, nums):
if nums == []:
return None
else:
# easy to forget to initialize
root = TreeNode(nums[len(nums)/2])
root.left = BSTinsertBalanced(root.left, nums[:len(nums)/2])
root.right = BSTinsertBalanced(root.right, nums[len(nums)/2+1:])
return root
newRoot = TreeNode(0)
return BSTinsertBalanced(newRoot, nums)```

]]>
http://yueguo1217.com/leetcode-108-convert-sorted-array-to-binary-search-tree-easy-80-in-python/feed/ 0
LeetCode : 599. Minimum Index Sum of Two Lists ( Easy 79 ) in Python http://yueguo1217.com/leetcode-599-minimum-index-sum-of-two-lists-easy-79-in-python/ http://yueguo1217.com/leetcode-599-minimum-index-sum-of-two-lists-easy-79-in-python/#respond Wed, 06 Dec 2017 20:41:58 +0000 http://yueguo1217.com/?p=871 Continue reading LeetCode : 599. Minimum Index Sum of Two Lists ( Easy 79 ) in Python ]]> Problem

Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings.

You need to help them find out their common interest with the least list index sum. If there is a choice tie between answers, output all of them with no order requirement. You could assume there always exists an answer.

Example 1:

```<b>Input:</b>
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"]
<b>Output:</b> ["Shogun"]
<b>Explanation:</b> The only restaurant they both like is "Shogun".```

Example 2:

```<b>Input:</b>
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["KFC", "Shogun", "Burger King"]
<b>Output:</b> ["Shogun"]
<b>Explanation:</b> The restaurant they both like and have the least index sum is "Shogun" with index sum 1 (0+1).```

Note:

1. The length of both lists will be in the range of [1, 1000].
2. The length of strings in both lists will be in the range of [1, 30].
3. The index is starting from 0 to the list length minus 1.
4. No duplicates in both lists.
Solution:

```class Solution(object):
def findRestaurant(self,list1, list2):
"""
:type list1: List[str]
:type list2: List[str]
:rtype: List[str]
"""
# O(N)
d = dict()
for i in xrange(len(list1)):
d[list1[i]] = [1,i]
for i in xrange(len(list2)):
if list2[i] in d.keys():
d[list2[i]] = [2, d[list2[i]] + i]
# filter out singles
theList = [[v,k] for k, v in d.items() if v == 2]
theDict = dict()
for i in theList:

if i in theDict.keys():
theDict[i] += [i]
else:
theDict[i] = [i]
return theDict[min(theDict.keys())]```

TODO: key & value swap:

Just create a new hashtable, and go through the original one one by one and insert.

Notice: shouldn’t be 1:N

]]>
http://yueguo1217.com/leetcode-599-minimum-index-sum-of-two-lists-easy-79-in-python/feed/ 0
LeetCode : 463. Island Perimeter ( Easy 78 ) in Python http://yueguo1217.com/leetcode-463-island-perimeter-easy-78-in-python/ http://yueguo1217.com/leetcode-463-island-perimeter-easy-78-in-python/#respond Wed, 06 Dec 2017 19:29:43 +0000 http://yueguo1217.com/?p=866 Continue reading LeetCode : 463. Island Perimeter ( Easy 78 ) in Python ]]> Problem

You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn’t have “lakes” (water inside that isn’t connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don’t exceed 100. Determine the perimeter of the island.

Example:

```[[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]

Explanation: The perimeter is the 16 yellow stripes in the image below:
<img src="https://leetcode.com/static/images/problemset/island.png" />```
IDEA:
1> how to build this matrix (right/down => add)
2> use it after building (#交界)
]]>
http://yueguo1217.com/leetcode-463-island-perimeter-easy-78-in-python/feed/ 0
LeetCode : 731. My Calendar II ( Median 55 ) in Python http://yueguo1217.com/leetcode-647-palindromic-substrings-median-54-in-python-2/ http://yueguo1217.com/leetcode-647-palindromic-substrings-median-54-in-python-2/#respond Sun, 03 Dec 2017 21:41:26 +0000 http://yueguo1217.com/?p=854 Continue reading LeetCode : 731. My Calendar II ( Median 55 ) in Python ]]> Problem

Implement a `MyCalendarTwo` class to store your events. A new event can be added if adding the event will not cause a triple booking.

Your class will have one method, `book(int start, int end)`. Formally, this represents a booking on the half open interval `[start, end)`, the range of real numbers `x` such that `start <= x < end`.

triple booking happens when three events have some non-empty intersection (ie., there is some time that is common to all 3 events.)

For each call to the method `MyCalendar.book`, return `true` if the event can be added to the calendar successfully without causing a triple booking. Otherwise, return `false` and do not add the event to the calendar.

Your class will be called like this: `MyCalendar cal = new MyCalendar();` `MyCalendar.book(start, end)`

Example 1:

```MyCalendar();
MyCalendar.book(10, 20); // returns true
MyCalendar.book(50, 60); // returns true
MyCalendar.book(10, 40); // returns true
MyCalendar.book(5, 15); // returns false
MyCalendar.book(5, 10); // returns true
MyCalendar.book(25, 55); // returns true
<b>Explanation:</b>
The first two events can be booked.  The third event can be double booked.
The fourth event (5, 15) can't be booked, because it would result in a triple booking.
The fifth event (5, 10) can be booked, as it does not use time 10 which is already double booked.
The sixth event (25, 55) can be booked, as the time in [25, 40) will be double booked with the third event;
the time [40, 50) will be single booked, and the time [50, 55) will be double booked with the second event.```

Note:

• The number of calls to `MyCalendar.book` per test case will be at most `1000`.
• In calls to `MyCalendar.book(start, end)``start` and `end` are integers in the range `[0, 10^9]`.

###### Solution candidate 1: (wrong)

Reason: could overlap with multiple nodes in a tree

```# use two trees, if could insert to at least one of two trees randomly, true, o.w., false
# !!! Note: corner case: both overlap, but overlaps are different !!! and could overlap with multiple nodes in a tree

class calendarNode:
def __init__(self, start, end):
self.val = [start, end]
self.left = None
self.right = None

class MyCalendarTwo(object):

def __init__(self):
self.calendarTree1 = calendarNode(0,0)
self.calendarTree2 = calendarNode(0,0)

def insertBook(self, root, start, end):
"""
:type root: calendarNode
:type start: int
:type end: int
:rtype: bool
"""
'''
won't work:
if root is None:
root = calendarNode(start, end)
return True
'''
if root is not None:
if end <= root.val:
if root.left is None:
root.left = calendarNode(start, end)
return [True, 0, 0]
else:
return self.insertBook(root.left, start, end)
elif start >= root.val:
if root.right is None:
root.right = calendarNode(start, end)
return [True, 0, 0]
else:
return self.insertBook(root.right, start, end)
else:
return [False, max(start, root.val), min(end, root.val)]

def book(self, start, end):
"""
:type start: int
:type end: int
:rtype: bool
"""
firstTreeResult = self.insertBook(self.calendarTree1, start, end)
if firstTreeResult:
return True
else:
secondTreeResult = self.insertBook(self.calendarTree2, start, end)
if firstTreeResult >= secondTreeResult or firstTreeResult <= secondTreeResult:
return True
else:
return False

# Your MyCalendarTwo object will be instantiated and called as such:
# obj = MyCalendarTwo()
# param_1 = obj.book(start,end)```

###### My Summary of idea:  O(NlogN)

Two trees: tree1, treeOverlap
a new book first compare to tree1
if no overlap with tree1, add to tree1
elif has overlap with tree1
if has overlap with treeOverlap, false
else add its overlap with tree1 to treeOverlap, true

DEBUG (TBC) — note: > O(NlonN) because split a overlap. TODO: don’t split overlap

```class calendarNode:
def __init__(self, start, end):
self.val = [start, end]
self.left = None
self.right = None

class MyCalendarTwo(object):

def __init__(self):
self.calendarTree1 = calendarNode(0,0)
self.calendarTreeOverlap = calendarNode(0,0)

def insertBook(self, root, start, end):
"""
:type root: calendarNode
:type start: int
:type end: int
:rtype: bool
"""
'''
won't work:
if root is None:
root = calendarNode(start, end)
return True
'''
if root is not None:
if end <= root.val:
if root.left is None:
root.left = calendarNode(start, end)
return True
else:
return self.insertBook(root.left, start, end)
elif start >= root.val:
if root.right is None:
root.right = calendarNode(start, end)
return True
else:
return self.insertBook(root.right, start, end)
else:
return False
else:
root = calendarNode(start, end)
return True

def findOverlapWithTree1AndInsertToTreeOverlap(self, tree1nodeRoot, start, end):
if tree1nodeRoot is not None:
if end <= tree1nodeRoot.val:
print("end <= tree1nodeRoot.val")
if tree1nodeRoot.left is not None:
print("  tree1nodeRoot.left is not None")
print("-----------")
return self.findOverlapWithTree1AndInsertToTreeOverlap(tree1nodeRoot.left, start, end)
print("-----------")
elif start >= tree1nodeRoot.val:
print("start >= tree1nodeRoot.val")
if tree1nodeRoot.right is not None:
print("  tree1nodeRoot.right is not None")
print("-----------")
return self.findOverlapWithTree1AndInsertToTreeOverlap(tree1nodeRoot.right, start, end)
print("-----------")
else:
print("else")
if start < tree1nodeRoot.val and end <= tree1nodeRoot.val:
print("  start < tree1nodeRoot.val and end <= tree1nodeRoot.val")
print("-----------")
return self.insertBook(self.calendarTreeOverlap, tree1nodeRoot.val, end) and self.findOverlapWithTree1AndInsertToTreeOverlap(tree1nodeRoot.left, start, tree1nodeRoot.val)
elif start < tree1nodeRoot.val and end > tree1nodeRoot.val:
print("  start < tree1nodeRoot.val and end > tree1nodeRoot.val")
print("-----------")
return self.insertBook(self.calendarTreeOverlap, tree1nodeRoot.val, tree1nodeRoot.val) and self.findOverlapWithTree1AndInsertToTreeOverlap(tree1nodeRoot.left, start, tree1nodeRoot.val) and self.findOverlapWithTree1AndInsertToTreeOverlap(tree1nodeRoot.right, tree1nodeRoot.val, end)
elif start >= tree1nodeRoot.val and end > tree1nodeRoot.val:
print("  start >= tree1nodeRoot.val and end > tree1nodeRoot.val")
print("-----------")
return self.insertBook(self.calendarTreeOverlap, start, tree1nodeRoot.val) and self.findOverlapWithTree1AndInsertToTreeOverlap(tree1nodeRoot.right, tree1nodeRoot.val, end)
elif start >= tree1nodeRoot.val and end <= tree1nodeRoot.val:
print("  start >= tree1nodeRoot.val and end <= tree1nodeRoot.val")
print("-----------")
return self.insertBook(self.calendarTreeOverlap, start, end)

else:
print("elseelse")
print("-----------")
return True # self.insertBook(self.calendarTreeOverlap, start, end)

def book(self, start, end):
"""
:type start: int
:type end: int
:rtype: bool
"""
if self.insertBook(self.calendarTree1, start, end):
return True
else:
return self.findOverlapWithTree1AndInsertToTreeOverlap(self.calendarTree1, start, end)

# Your MyCalendarTwo object will be instantiated and called as such:
obj = MyCalendarTwo()
for j in [[47,50],[1,10],[27,36],[40,47],[20,27],[15,23],[10,18],[27,36],[17,25],[8,17],[24,33],[23,28],[21,27],[47,50],[14,21],[26,32],[16,21],[2,7],[24,33],[6,13],[44,50],[33,39],[30,36],[6,15],[21,27],[49,50],[38,45],[4,12],[46,50],[13,21]]:
print j
param = obj.book(j,j)```

]]>
http://yueguo1217.com/leetcode-647-palindromic-substrings-median-54-in-python-2/feed/ 0
Algorithm Practice Notes http://yueguo1217.com/bst-notes/ http://yueguo1217.com/bst-notes/#respond Sun, 03 Dec 2017 21:12:38 +0000 http://yueguo1217.com/?p=852 Continue reading Algorithm Practice Notes ]]> BST
###### Basis:

symbol table API  (Implement: recursion or non-recursion)

1. get() / search() — no change to the tree
2. put() / insert() — change the val of a node OR new node add to the tree, need to return a node  [note: any new node could 1> update a existing node(no change if val the same) 2> add to the leaf  never add to the middle
3. min() & max()
4. floor() & ceiling()
5. select() & rank()  — use size
6. deleteMin() & deleteMax() & delete()
7. range searching — based on value + inorder traversal idea
###### Categories:
1.  Variants of symbol table API.

##### Hash Table
]]>
http://yueguo1217.com/bst-notes/feed/ 0
LeetCode : 530. Minimum Absolute Difference in BST ( Easy 77 ) in Python http://yueguo1217.com/leetcode-530-minimum-absolute-difference-in-bst-easy-77-in-python/ http://yueguo1217.com/leetcode-530-minimum-absolute-difference-in-bst-easy-77-in-python/#respond Sun, 03 Dec 2017 19:56:33 +0000 http://yueguo1217.com/?p=846 Problem

Given a binary search tree with non-negative values, find the minimum absolute difference between values of any two nodes.

Example:

```<b>Input:</b>

1
\
3
/
2

<b>Output:</b>
1

<b>Explanation:</b>
The minimum absolute difference is 1, which is the difference between 2 and 1 (or between 2 and 3).```

Note: There are at least two nodes in this BST.

###### Solution O(N)

```# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
def getMinimumDifference(self, root):
"""
:type root: TreeNode
:rtype: int
"""
# 1> inorder traversal, then each pair of neighbors' diff
# 2> each pair of neighbors' diff + grandparent vs lefts' right min grandgrand...son +  + grandparent vs rights' left min grandgrand...son complecated)
def inorderTraversal(root, sortList):
if root is not None:
inorderTraversal(root.left, sortList)
sortList.append(root.val)
inorderTraversal(root.right, sortList)
sortList = list()
inorderTraversal(root, sortList)
return min([abs(x-y) for x, y in zip(sortList + [sortList], [sortList[-1]] + sortList)])```

Solution 2 (Similar idea with solution 1, use BST directly with a global record of previous min) from link solution 1

```# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

import sys
class Solution(object):
def __init__(self):
self.prev = -1
self.minSoFar = sys.maxint
def getMinimumDifference(self, root):
"""
:type root: TreeNode
:rtype: int
"""
# idea from https://leetcode.com/problems/minimum-absolute-difference-in-bst/discuss/ solution 1
if root is None:
return sys.maxint
else:
self.getMinimumDifference(root.left)
if self.prev != -1:
self.minSoFar = min(self.minSoFar, abs(self.prev - root.val))
self.prev = root.val
self.getMinimumDifference(root.right)
return self.minSoFar```

]]>
http://yueguo1217.com/leetcode-530-minimum-absolute-difference-in-bst-easy-77-in-python/feed/ 0
LeetCode : 653. Two Sum IV – Input is a BST ( Easy 76 ) in Python http://yueguo1217.com/leetcode-653-two-sum-iv-input-is-a-bst-easy-76-in-python/ http://yueguo1217.com/leetcode-653-two-sum-iv-input-is-a-bst-easy-76-in-python/#respond Fri, 01 Dec 2017 02:23:31 +0000 http://yueguo1217.com/?p=841 Problem

Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target.

Example 1:

```<b>Input:</b>
5
/ \
3   6
/ \   \
2   4   7

Target = 9

<b>Output:</b> True```

Example 2:

```<b>Input:</b>
5
/ \
3   6
/ \   \
2   4   7

Target = 28

<b>Output:</b> False```

###### O(N) — Inorder traversal + two pointers

```# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
def findTarget(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: bool
"""
# DFS extend to a list (inorder)
bstList = list()
def dfs(root):
if root:
dfs(root.left)
bstList.append(root.val)
dfs(root.right)
dfs(root)
# two pointers
i,j = 0, len(bstList)-1
while i < j:
if bstList[i] + bstList[j] == k:
return True
elif bstList[i] + bstList[j] < k:
i += 1
else:
j -= 1
return False```

###### O(N) – hashtable (O(1) insert and search)

```# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
def findTarget(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: bool
"""
# hashtable
theSet = set()
def findTargetHelper(root, k):
if root is not None:
if k - root.val in theSet:
return True
else: