Bladeren bron

Merge branch 'master' of ssh://111.230.181.241:1111/ikachan/leetcode-go

dengxinyi 6 jaren geleden
bovenliggende
commit
b1039848cf

+ 7 - 0
easy/268.missing-number.go

@@ -0,0 +1,7 @@
+func missingNumber(nums []int) int {
+	n, sum := len(nums), 0
+	for _, i := range nums {
+		sum += i
+	}
+	return (n+1)*n/2 - sum
+}

+ 33 - 0
easy/278.first-bad-version.js

@@ -0,0 +1,33 @@
+/**
+ * Definition for isBadVersion()
+ * 
+ * @param {integer} version number
+ * @return {boolean} whether the version is bad
+ * isBadVersion = function(version) {
+ *     ...
+ * };
+ */
+
+/**
+ * @param {function} isBadVersion()
+ * @return {function}
+ */
+var solution = function(isBadVersion) {
+    /**
+     * @param {integer} n Total versions
+     * @return {integer} The first bad version
+     */
+    return function(n) {
+        let beg = 1, end = n, gap = 0
+		while (beg < end) {
+			if (gap == end - beg) break
+			gap = end - beg
+			let mid = Math.round((beg + end) / 2)
+			let isBad = isBadVersion(mid)
+			if (isBad) end = mid
+			else if (!isBad) beg = mid + 1
+		}
+		if (isBadVersion(beg)) return beg
+		return end
+    }
+}

+ 16 - 0
easy/283.move-zeroes.go

@@ -0,0 +1,16 @@
+func moveZeroes(nums []int)  {
+	n := len(nums)
+	ptr, cnt := 0, 0
+	for i := 0; i < n && ptr < n-cnt; i++ {
+		if nums[i] == 0 {
+			cnt++
+		} else {
+			nums[ptr] = nums[i]
+			ptr++
+		}
+	}
+	for ptr < n {
+		nums[ptr] = 0
+		ptr++
+	}
+}

+ 23 - 0
easy/290.word-pattern.go

@@ -0,0 +1,23 @@
+func wordPattern(pattern string, str string) bool {
+	words := strings.Split(str, " ")
+	if len(words) != len(pattern) {
+		return false
+	}
+	r2s := make(map[rune]string)
+	s2r := make(map[string]rune)
+	for i, p := range pattern {
+		if s, ok := r2s[p]; ok {
+			if s != words[i] {
+				return false
+			}
+		}
+		if r, ok := s2r[words[i]]; ok {
+			if r != p {
+				return false
+			}
+		}
+		r2s[p] = words[i]
+		s2r[words[i]] = p
+	}
+	return true
+}

+ 3 - 0
easy/292.nim-game.go

@@ -0,0 +1,3 @@
+func canWinNim(n int) bool {
+	return n % 4 != 0
+}

+ 81 - 0
hard/212.word-search-ii.go

@@ -0,0 +1,81 @@
+func findWords(board [][]byte, words []string) (ans []string) {
+	trie := &TrieNode{}
+	for i := range words {
+		trie.Insert(words[i])
+	}
+	for y := range board {
+		for x := range board[y] {
+			DFS(board, trie, trie, x, y, &ans, []byte{})
+		}
+	}
+	return
+}
+
+func DFS(board [][]byte, trie, curr *TrieNode, x, y int, ans *[]string, prev []byte) {
+	ch := board[y][x]
+	if ch == '*' { // Visited
+		return
+	}
+	curr = curr.OneStepSearch(ch)
+	if curr == nil {
+		return
+	}
+	path := make([]byte, len(prev))
+	copy(path, prev)
+	path = append(path, ch)
+	if curr.IsKey {
+		*ans = append(*ans, string(path))
+		trie.Delete(path)
+	}
+	board[y][x] = '*' // Mark (x, y) as visited
+	if 0 < x {
+		DFS(board, trie, curr, x-1, y, ans, path)
+	}
+	if 0 < y {
+		DFS(board, trie, curr, x, y-1, ans, path)
+	}
+	if x < len(board[0])-1 {
+		DFS(board, trie, curr, x+1, y, ans, path)
+	}
+	if y < len(board)-1 {
+		DFS(board, trie, curr, x, y+1, ans, path)
+	}
+	board[y][x] = ch
+}
+
+type TrieNode struct {
+	Cnt      int
+	IsKey    bool
+	Children *[26]TrieNode
+}
+
+func (root *TrieNode) Insert(word string) {
+	for i := range word {
+		if root.Children == nil {
+			root.Children = &[26]TrieNode{}
+		}
+		root = &root.Children[int(word[i]-'a')]
+		root.Cnt++
+	}
+	root.IsKey = true
+}
+
+func (root *TrieNode) Delete(word []byte) {
+	for i := range word {
+		root = &root.Children[int(word[i]-'a')]
+		root.Cnt--
+	}
+	root.IsKey = false
+}
+
+func (root *TrieNode) OneStepSearch(ch byte) *TrieNode {
+	if root.Children == nil {
+		return nil
+	}
+	root = &root.Children[int(ch-'a')]
+	if root.Cnt == 0 {
+		return nil
+	}
+	return root
+}
+

+ 33 - 0
hard/214.shortest-palindrome.go

@@ -0,0 +1,33 @@
+import (
+	"strings"
+)
+
+func shortestPalindrome(s string) string {
+	l := len(s)
+	if l <= 1 {
+		return s
+	}
+	var i, j int
+	for i = l; i <= 2*l; i++ { // i means the length of the shortest palindrome
+		if i%2 == 1 { // Odd
+			for j = 1; 0 <= l-1-i/2-j && s[l-1-i/2-j] == s[l-1-i/2+j]; j++ {
+			}
+			if l-1-i/2-j < 0 {
+				break
+			}
+		} else { // Even
+			for j = 1; 0 <= l-i/2-j && s[l-i/2-j] == s[l-1-i/2+j]; j++ {
+			}
+			if l-i/2-j < 0 {
+				break
+			}
+		}
+	}
+	idx := l - 1 - i/2 + j
+	var ans strings.Builder
+	for i := l-1; idx <= i; i-- {
+		ans.WriteByte(s[i])
+	}
+	ans.WriteString(s)
+	return ans.String()
+}

+ 140 - 0
hard/218.the-skyline-problem.go

@@ -0,0 +1,140 @@
+func getSkyline(buildings [][]int) [][]int {
+	ans := [][]int{{-1, -1}} // Prevent out of index error
+	var sl SortedList
+	pq := NewPQ()
+	length := len(buildings)
+	for i, top := 0, 0; i < length || !pq.Empty(); {
+		if i == length || (!pq.Empty() && pq.Peek().(Pair)._1 <= buildings[i][0]) { // Delete
+			p := pq.Dequeue().(Pair)
+			sl.Delete(p._2)
+			if p._1 == ans[top][0] {
+				ans[top][1] = sl.Max()
+			} else {
+				ans = append(ans, []int{p._1, sl.Max()})
+				top++
+			}
+		} else { // Insert
+			l, r, h := buildings[i][0], buildings[i][1], buildings[i][2]
+			sl.Insert(h)
+			pq.Enqueue(Pair{r, h})
+			i++
+			if l == ans[top][0] {
+				ans[top][1] = sl.Max()
+			} else {
+				ans = append(ans, []int{l, sl.Max()})
+				top++
+			}
+		}
+		if ans[top][1] == ans[top-1][1] { // If the height is same, pop the top of ans
+			ans = ans[:top]
+			top--
+		}
+	}
+	return ans[1:]
+}
+
+type SortedList struct {
+	List []int
+	Len  int
+}
+
+func (sl SortedList) Max() int {
+	if sl.Len == 0 {
+		return 0
+	}
+	return sl.List[sl.Len-1]
+}
+
+func (sl SortedList) Search(x int) int {
+	beg, end := 0, sl.Len
+	for beg < end {
+		mid := beg + (end-beg)/2
+		if x < sl.List[mid] {
+			end = mid
+		} else if sl.List[mid] < x {
+			beg = mid + 1
+		} else {
+			return mid
+		}
+	}
+	return beg
+}
+
+func (sl *SortedList) Insert(x int) {
+	idx := sl.Search(x)
+	sl.List = append(sl.List, 0)
+	copy(sl.List[idx+1:], sl.List[idx:])
+	sl.List[idx] = x
+	sl.Len++
+}
+
+func (sl *SortedList) Delete(x int) {
+	idx := sl.Search(x)
+	copy(sl.List[idx:], sl.List[idx+1:])
+	sl.List = sl.List[:sl.Len-1]
+	sl.Len--
+}
+
+type Pair struct {
+	_1 int
+	_2 int
+}
+
+func (p Pair) Less(q Item) bool { return p._1 < q.(Pair)._1 }
+
+type PQ struct {
+	Queue []Item
+	Len   int
+}
+
+type Item interface {
+	Less(than Item) bool
+}
+
+func NewPQ() (pq PQ) {
+	pq.Queue = make([]Item, 1)
+	return
+}
+
+func (pq PQ) Less(i, j int) bool { return pq.Queue[i].Less(pq.Queue[j]) }
+func (pq PQ) Swap(i, j int)      { pq.Queue[i], pq.Queue[j] = pq.Queue[j], pq.Queue[i] }
+
+func (pq PQ) Empty() bool { return pq.Len == 0 }
+
+func (pq PQ) Peek() Item { return pq.Queue[1] }
+
+func (pq *PQ) Enqueue(item Item) {
+	pq.Queue = append(pq.Queue, item)
+	pq.Len++
+	pq.swim(pq.Len)
+}
+
+func (pq *PQ) Dequeue() Item {
+	pq.Swap(1, pq.Len)
+	item := pq.Queue[pq.Len]
+	pq.Queue = pq.Queue[:pq.Len]
+	pq.Len--
+	pq.sink(1)
+	return item
+}
+
+func (pq PQ) swim(i int) {
+	for 1 < i && pq.Queue[i].Less(pq.Queue[i/2]) {
+		pq.Swap(i, i/2)
+		i /= 2
+	}
+}
+
+func (pq PQ) sink(i int) {
+	for j := 2 * i; j <= pq.Len; j *= 2 {
+		if j+1 <= pq.Len && pq.Queue[j+1].Less(pq.Queue[j]) {
+			j++
+		}
+		if !pq.Queue[j].Less(pq.Queue[i]) {
+			break
+		}
+		pq.Swap(i, j)
+		i = j
+	}
+}
+

+ 82 - 0
hard/224.basic-calculator.go

@@ -0,0 +1,82 @@
+import (
+	"strings"
+	"strconv"
+)
+
+func calculate(s string) int {
+	s = strings.Replace(s, " ", "", -1)
+	nums := make([]int, 0)
+	ops := make([]byte, 0)
+	l, m, n := len(s), 0, 0
+	beg := -1
+	push := false
+	for i := 0; i < l; i++ {
+		switch s[i] {
+		case '+', '-':
+			var num int
+			if beg != -1 {
+				num = atoi(s, beg, i)
+				beg = -1
+			} else {
+				num = nums[n-1]
+				nums = nums[:n-1]
+				n--
+			}
+			if !push && m != 0 { // Pop
+				aopb(&nums[n-1], ops[m-1], num)
+				ops = ops[:m-1]
+				m--
+			} else {
+				nums = append(nums, num)
+				n++
+				push = false
+			}
+			ops = append(ops, s[i])
+			m++
+		case '(':
+			push = true
+		case ')':
+			var num int
+			if beg != -1 {
+				num = atoi(s, beg, i)
+				beg = -1
+			} else {
+				num = nums[n-1]
+				nums = nums[:n-1]
+				n--
+			}
+			if m != 0 { // Handle expressions like (num)
+				aopb(&nums[n-1], ops[m-1], num)
+				ops = ops[:m-1]
+				m--
+			} else {
+				nums = append(nums, num)
+				n++
+			}
+		default: // Case '0', '1', ... , '9'
+			if beg == -1 {
+				beg = i
+			}
+		}
+	}
+	if beg != -1 {
+		nums = append(nums, atoi(s, beg, l))
+	}
+	if len(ops) != 0 {
+		aopb(&nums[0], ops[0], nums[1])
+	}
+	return nums[0]
+}
+
+func atoi(s string, beg, end int) int {
+	i, _ := strconv.Atoi(s[beg:end])
+	return i
+}
+
+func aopb(a *int, op byte, b int) {
+	switch op {
+	case '+': *a += b
+	case '-': *a -= b
+	}
+}
+

+ 16 - 0
hard/233.number-of-digit-one.go

@@ -0,0 +1,16 @@
+func countDigitOne(n int) (ones int) {
+	// Every 1000 has 100 ones at hundreds digit, every 100 has 10 ones at tens digit, ...
+	// Assume the base of curr digit (like 1000) is m, then a = n / m, b = n % m,
+	// If curr digit is 0, the ones of curr dight is a / 10 * base;
+	// curr digit is 1, the ones is a / 10 * base + (b + 1);
+	// curr digit is 2~9, the ones is (a / 10 + 1) * base.
+	// So, the ones of curr digit is (a + 8) / 10 * base + (a % 10 == 1) * (b + 1)
+	for m := 1; m <= n; m *= 10 {
+		a, b := n/m, n%m
+		ones += (a + 8) / 10 * m
+		if a%10 == 1 {
+			ones += b + 1
+		}
+	}
+	return
+}

+ 81 - 0
hard/239.sliding-window-maximum.go

@@ -0,0 +1,81 @@
+import (
+	"container/list"
+)
+
+func maxSlidingWindow(nums []int, k int) (ans []int) {
+	n := len(nums)
+	if n <= 1 || k == 1 {
+		return nums
+	}
+	l := list.New()
+	l.PushBack(0)
+	for i := 1; i < n; i++ {
+		if front := l.Front(); front.Value.(int) <= i-k {
+			l.Remove(front)
+		}
+		for back := l.Back(); back != nil && nums[back.Value.(int)] <= nums[i]; back = l.Back() {
+			l.Remove(back)
+		}
+		l.PushBack(i)
+		if k-1 <= i {
+			ans = append(ans, nums[l.Front().Value.(int)])
+		}
+	}
+	return
+}
+
+func maxSlidingWindowSlow(nums []int, k int) (ans []int) { // If use BST, O(nlog(k))
+	n := len(nums) // Actually, just abit slower.
+	if n <= 1 || k == 1 {
+		return nums
+	}
+	var sl SortedList
+	for i := 0; i < n; i++ {
+		if k <= i {
+			ans = append(ans, sl.Max())
+			sl.Delete(nums[i-k])
+		}
+		sl.Insert(nums[i])
+	}
+	return append(ans, sl.Max())
+}
+
+type SortedList struct {
+	List []int
+	Len  int
+}
+
+func (sl SortedList) Max() int {
+	return sl.List[sl.Len-1]
+}
+
+func (sl SortedList) Search(x int) int {
+	beg, end := 0, sl.Len
+	for beg < end {
+		mid := beg + (end-beg)/2
+		if x < sl.List[mid] {
+			end = mid
+		} else if sl.List[mid] < x {
+			beg = mid+1
+		} else {
+			return mid
+		}
+	}
+	return beg
+}
+
+func (sl *SortedList) Insert(x int) {
+	idx := sl.Search(x)
+	sl.List = append(sl.List, 0)
+	copy(sl.List[idx+1:], sl.List[idx:])
+	sl.List[idx] = x
+	sl.Len++
+}
+
+func (sl *SortedList) Delete(x int) {
+	idx := sl.Search(x)
+	copy(sl.List[idx:], sl.List[idx+1:])
+	sl.Len--
+	sl.List = sl.List[:sl.Len]
+}
+

+ 93 - 0
hard/273.integer-to-english-words.go

@@ -0,0 +1,93 @@
+func numberToWords(num int) string {
+	if num == 0 {
+		return "Zero"
+	}
+	return ntowRecurse(num)
+}
+
+func ntowRecurse(num int) (res string) {
+	if num/1000000000 != 0 {
+		res += ntowRecurse(num/1000000000) + getWord(0) + getWord(1000000000) + getWord(0) + ntowRecurse(num%1000000000)
+	} else if num/1000000 != 0 {
+		res += ntowRecurse(num/1000000) + getWord(0) + getWord(1000000) + getWord(0) + ntowRecurse(num%1000000)
+	} else if num/1000 != 0 {
+		res += ntowRecurse(num/1000) + getWord(0) + getWord(1000) + getWord(0) + ntowRecurse(num%1000)
+	} else if num/100 != 0 {
+		res += ntowRecurse(num/100) + getWord(0) + getWord(100) + getWord(0) + ntowRecurse(num%100)
+	} else if 20 <= num {
+		res += getWord(num-num%10) + getWord(0) + ntowRecurse(num%10)
+	} else if num != 0 {
+		res = getWord(num)
+	}
+	return strings.Trim(res, " ")
+}
+
+func getWord(num int) string {
+	switch num {
+	case 1:
+		return "One"
+	case 2:
+		return "Two"
+	case 3:
+		return "Three"
+	case 4:
+		return "Four"
+	case 5:
+		return "Five"
+	case 6:
+		return "Six"
+	case 7:
+		return "Seven"
+	case 8:
+		return "Eight"
+	case 9:
+		return "Nine"
+	case 10:
+		return "Ten"
+	case 11:
+		return "Eleven"
+	case 12:
+		return "Twelve"
+	case 13:
+		return "Thirteen"
+	case 14:
+		return "Fourteen"
+	case 15:
+		return "Fifteen"
+	case 16:
+		return "Sixteen"
+	case 17:
+		return "Seventeen"
+	case 18:
+		return "Eighteen"
+	case 19:
+		return "Nineteen"
+	case 20:
+		return "Twenty"
+	case 30:
+		return "Thirty"
+	case 40:
+		return "Forty"
+	case 50:
+		return "Fifty"
+	case 60:
+		return "Sixty"
+	case 70:
+		return "Seventy"
+	case 80:
+		return "Eighty"
+	case 90:
+		return "Ninety"
+	case 100:
+		return "Hundred"
+	case 1000:
+		return "Thousand"
+	case 1000000:
+		return "Million"
+	case 1000000000:
+		return "Billion"
+	default:
+		return " "
+	}
+}
+

+ 36 - 0
hard/282.expression-add-operators.go

@@ -0,0 +1,36 @@
+func addOperators(num string, target int) (res []string) {
+	strlen := len(num)
+	exp := make([]byte, 2*strlen)
+	DFS(num, strlen, target, 0, &exp, 0, 0, 0, &res) // O(n^4) time, O(n) space
+	return
+}
+
+func DFS(num string, strlen, target, pos int, exp *[]byte, length, prev, curr int, res *[]string) {
+	if pos == strlen && curr == target {
+		*res = append(*res, string((*exp)[0:length]))
+		return
+	}
+	n, i, l := 0, pos, length
+	if pos != 0 {
+		length++
+	}
+	for i < strlen {
+		if num[pos] == '0' && pos < i { // Avoid leading zero
+			break
+		}
+		n = n*10 + int(num[i]-'0')
+		(*exp)[length] = num[i]
+		length, i = length+1, i+1
+		if pos == 0 { // Init DFS
+			DFS(num, strlen, target, i, exp, length, n, n, res)
+			continue
+		}
+		(*exp)[l] = '+'
+		DFS(num, strlen, target, i, exp, length, n, curr+n, res)
+		(*exp)[l] = '-'
+		DFS(num, strlen, target, i, exp, length, -n, curr-n, res)
+		(*exp)[l] = '*'
+		DFS(num, strlen, target, i, exp, length, prev*n, curr-prev+prev*n, res)
+	}
+}
+

+ 93 - 0
hard/295.find-median-from-data-stream.go

@@ -0,0 +1,93 @@
+import (
+	"container/heap"
+)
+
+type MedianFinder struct {
+	max MaxHeap  // The left part (smaller part) of data
+	min MinHeap  // The right part of data
+	odd bool
+}
+
+/** initialize your data structure here. */
+func Constructor() (mf MedianFinder) {
+	return
+}
+
+func (this *MedianFinder) AddNum(num int) {
+	if this.max.length == 0 || num < this.max.Max() {
+		heap.Push(&this.max, num)
+		if this.max.length-this.min.length == 2 {
+			heap.Push(&this.min, heap.Pop(&this.max))
+		}
+	} else {
+		heap.Push(&this.min, num)
+		if this.min.length-this.max.length == 1 {
+			heap.Push(&this.max, heap.Pop(&this.min))
+		}
+	}
+	this.odd = !this.odd
+}
+
+func (this *MedianFinder) FindMedian() float64 {
+	if this.odd {
+		return float64(this.max.Max())
+	}
+	return float64(this.max.Max()+this.min.Min()) / 2.0
+}
+
+type MaxHeap struct {
+	heap   []int
+	length int
+}
+
+func (max MaxHeap) Len() int           { return max.length }
+func (max MaxHeap) Less(i, j int) bool { return max.heap[i] > max.heap[j] }
+func (max MaxHeap) Swap(i, j int)      { max.heap[i], max.heap[j] = max.heap[j], max.heap[i] }
+
+func (max MaxHeap) Max() int {
+	return max.heap[0]
+}
+
+func (max *MaxHeap) Push(x interface{}) {
+	max.heap = append(max.heap, x.(int))
+	max.length++
+}
+
+func (max *MaxHeap) Pop() interface{} {
+	max.length--
+	top := max.heap[max.length]
+	max.heap = max.heap[:max.length]
+	return top
+}
+
+type MinHeap struct {
+	heap   []int
+	length int
+}
+
+func (min MinHeap) Len() int           { return min.length }
+func (min MinHeap) Less(i, j int) bool { return min.heap[i] < min.heap[j] }
+func (min MinHeap) Swap(i, j int)      { min.heap[i], min.heap[j] = min.heap[j], min.heap[i] }
+
+func (min MinHeap) Min() int {
+	return min.heap[0]
+}
+
+func (min *MinHeap) Push(x interface{}) {
+	min.heap = append(min.heap, x.(int))
+	min.length++
+}
+
+func (min *MinHeap) Pop() interface{} {
+	min.length--
+	top := min.heap[min.length]
+	min.heap = min.heap[:min.length]
+	return top
+}
+
+/**
+ * Your MedianFinder object will be instantiated and called as such:
+ * obj := Constructor();
+ * obj.AddNum(num);
+ * param_2 := obj.FindMedian();
+ */

+ 66 - 0
hard/297.serialize-and-deserialize-binary-tree.java

@@ -0,0 +1,66 @@
+import java.util.LinkedList;
+
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+public class Codec {
+
+    // Encodes a tree to a single string.
+    public String serialize(TreeNode root) { // Level-order traversal
+        StringBuilder sb = new StringBuilder();
+		LinkedList<TreeNode> list = new LinkedList<TreeNode>();
+		list.add(root);
+		TreeNode curr;
+		while (!list.isEmpty()) {
+			curr = list.poll();
+			if (curr == null) {
+				sb.append("null,");
+				continue;
+			}
+			sb.append(curr.val);
+			sb.append(',');
+			list.add(curr.left);
+			list.add(curr.right);
+		}
+		sb.deleteCharAt(sb.length()-1); // Remove the last ','
+		return sb.toString();
+    }
+
+    // Decodes your encoded data to tree.
+    public TreeNode deserialize(String data) {
+		String[] strs = data.split(",");
+		if (strs[0].equals("null")) return null; // Root is null
+		TreeNode root = new TreeNode(Integer.parseInt(strs[0]));
+		LinkedList<TreeNode> list = new LinkedList<TreeNode>();
+		list.add(root);
+		int idx = 1;
+		while (!list.isEmpty()) {
+			TreeNode curr = list.poll();
+			if (idx < strs.length) {
+				if (!strs[idx].equals("null")) {
+					curr.left = new TreeNode(Integer.parseInt(strs[idx]));
+					list.add(curr.left);
+				}
+				idx++;
+			}
+			if (idx < strs.length) {
+				if (!strs[idx].equals("null")) {
+					curr.right = new TreeNode(Integer.parseInt(strs[idx]));
+					list.add(curr.right);
+				}
+				idx++;
+			}
+		}
+        return root;
+    }
+}
+
+// Your Codec object will be instantiated and called as such:
+// Codec codec = new Codec();
+// codec.deserialize(codec.serialize(root));

+ 17 - 0
medium/228.summary-ranges.go

@@ -0,0 +1,17 @@
+import (
+	"fmt"
+)
+
+func summaryRanges(nums []int) (ranges []string) {
+	for beg, end := 0, 0; beg < len(nums); beg = end {
+		for end = beg + 1; end < len(nums) && nums[end]-nums[end-1] == 1; end++ {
+		}
+		if beg+1 == end {
+			ranges = append(ranges, fmt.Sprintf("%d", nums[beg]))
+		} else {
+			ranges = append(ranges, fmt.Sprintf("%d->%d", nums[beg], nums[end-1]))
+		}
+	}
+	return
+}
+

+ 35 - 0
medium/229.majority-element-ii.go

@@ -0,0 +1,35 @@
+func majorityElement(nums []int) (ans []int) {
+	n1, n2, c1, c2 := 0, 0, 0, 0
+	for _, n := range nums { // At most 2 majority elements occur more than n/3 times.
+	// Use two counters to vote the occurence of the numbers.
+		switch {
+		case n == n1:
+			c1++
+		case n == n2:
+			c2++
+		case c1 == 0:
+			n1, c1 = n, 1
+		case c2 == 0:
+			n2, c2 = n, 1
+		default:
+			c1, c2 = c1-1, c2-1
+		}
+	}
+	c1, c2 = 0, 0
+	for _, n := range nums {
+		switch n {
+		case n1:
+			c1++
+		case n2:
+			c2++
+		}
+	}
+	if len(nums)/3 < c1 {
+		ans = append(ans, n1)
+	}
+	if len(nums)/3 < c2 {
+		ans = append(ans, n2)
+	}
+	return
+}
+

+ 25 - 0
medium/230.kth-smallest-element-in-a-bst.go

@@ -0,0 +1,25 @@
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func kthSmallest(root *TreeNode, k int) (val int) {
+	traversalKth(root, &k, &val)
+	return
+}
+
+func traversalKth(node *TreeNode, k *int, val *int) {
+	if node == nil {
+		return
+	}
+	traversalKth(node.Left, k, val)
+	(*k)--
+	if *k == 0 {
+		*val = node.Val
+		return
+	}
+	traversalKth(node.Right, k, val)
+}

+ 27 - 0
medium/236.lowest-common-ancestor-of-a-binary-tree.js

@@ -0,0 +1,27 @@
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val) {
+ *     this.val = val;
+ *     this.left = this.right = null;
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {TreeNode} p
+ * @param {TreeNode} q
+ * @return {TreeNode}
+ */
+var lowestCommonAncestor = function(root, p, q) {
+	let la = null
+	const traversal = function(root, p, q) {
+		let set1 = [], set2 = []
+		if (root.left !== null) set1 = traversal(root.left, p, q)
+		if (root.right !== null) set2 = traversal(root.right, p, q)
+		let set3 = new Set([...set1, ...set2])
+		if (root === p || root === q) set3.add(root)
+		if (set3.has(p) && set3.has(q)) { la = root; return [] }
+		return set3
+	}
+	traversal(root, p, q)
+	return la
+}

+ 48 - 0
medium/238.product-of-array-except-self.go

@@ -0,0 +1,48 @@
+func productExceptSelfLong(nums []int) []int {
+	l := len(nums)
+	ans := make([]int, l)
+	zero := false
+	zeroIdx, product := -1, 1
+	for i := 0; i < l; i++ {
+		if nums[i] != 0 {
+			product *= nums[i]
+		} else {
+			if zero {
+				return ans
+			}
+			zero = true
+			zeroIdx = i
+		}
+	}
+	if zero {
+		ans[zeroIdx] = product
+		return ans
+	}
+	for i := 0; i < l; i++ {
+		ans[i] = product / nums[i]
+	}
+	return ans
+}
+
+func productExceptSelf(nums []int) []int {
+	l := len(nums)
+	ans := make([]int, l)
+	memset(ans, 1)
+	for i := 1; i < l; i++ {
+		ans[i] = ans[i-1] * nums[i-1]
+	}
+	for i, tmp := l-2, 1; 0 <= i; i-- {
+		tmp *= nums[i+1]
+		ans[i] *= tmp
+	}
+	return ans
+}
+
+func memset(a []int, v int) {
+	a[0] = v
+	l := len(a)
+	for bp := 1; bp < l; bp *= 2 {
+		copy(a[bp:], a[:bp])
+	}
+}
+

+ 51 - 0
medium/240.search-a-2d-matrix-ii.go

@@ -0,0 +1,51 @@
+func searchMatrix(matrix [][]int, target int) bool {
+	yEnd := len(matrix)
+	if yEnd == 0 {
+		return false
+	}
+	xEnd := len(matrix[0])
+	return searchPartOf(matrix, 0, xEnd, 0, yEnd, target)
+}
+
+func searchPartOf(matrix [][]int, xBeg, xEnd, yBeg, yEnd, target int) bool {
+	m, n := yEnd-yBeg, xEnd-xBeg
+	if m == 0 || n == 0 {
+		return false
+	}
+	if m == 1 { // If m is 1 or n is 1, fall back to binary search.
+		beg, end := xBeg, xEnd
+		for beg < end {
+			mid := beg + (end-beg)/2
+			if matrix[yBeg][mid] < target {
+				beg = mid + 1
+			} else if target < matrix[yBeg][mid] {
+				end = mid
+			} else {
+				return true
+			}
+		}
+		return false
+	} else if n == 1 {
+		beg, end := yBeg, yEnd
+		for beg < end {
+			mid := beg + (end-beg)/2
+			if matrix[mid][xBeg] < target {
+				beg = mid + 1
+			} else if target < matrix[mid][xBeg] {
+				end = mid
+			} else {
+				return true
+			}
+		}
+		return false
+	}
+	if target < matrix[yBeg][xBeg] || matrix[yEnd-1][xEnd-1] < target {
+		return false
+	}
+	xMid, yMid := xBeg+(xEnd-xBeg)/2, yBeg+(yEnd-yBeg)/2
+	return searchPartOf(matrix, xBeg, xMid, yBeg, yMid, target) || // Split the whole matrix into 4 parts.
+		searchPartOf(matrix, xMid, xEnd, yBeg, yMid, target) ||
+		searchPartOf(matrix, xBeg, xMid, yMid, yEnd, target) ||
+		searchPartOf(matrix, xMid, xEnd, yMid, yEnd, target)
+}
+

+ 33 - 0
medium/241.different-ways-to-add-parentheses.go

@@ -0,0 +1,33 @@
+import (
+	"strconv"
+)
+
+var m map[string][]int = make(map[string][]int)
+
+func diffWaysToCompute(input string) (ans []int) {
+	if _, ok := m[input]; ok {
+		return m[input]
+	}
+	for i := range input { // Divide and conquer, use every operator to split input into 2 smaller sub-problems.
+		if ch := input[i]; ch == '+' || ch == '-' || ch == '*' {
+			for _, l := range diffWaysToCompute(input[:i]) {
+				for _, r := range diffWaysToCompute(input[i+1:]) {
+					if ch == '+' {
+						ans = append(ans, l+r)
+					} else if ch == '-' {
+						ans = append(ans, l-r)
+					} else {
+						ans = append(ans, l*r)
+					}
+				}
+			}
+		}
+	}
+	if len(ans) == 0 { // No operator, just a number
+		n, _ := strconv.Atoi(input)
+		ans = append(ans, n)
+	}
+	m[input] = ans
+	return
+}
+

+ 19 - 0
medium/260.single-number-iii.go

@@ -0,0 +1,19 @@
+func singleNumber(nums []int) []int {
+	n, a, b := len(nums), 0, 0
+	for i := 0; i < n; i++ {
+		a ^= nums[i]
+	}
+	mask := 1
+	for mask & a == 0 {
+		mask <<= 1
+	}
+	a = 0
+	for i := 0; i < n; i++ {
+		if nums[i] & mask == 0 { // Use the mask to split all nums into 2 groups
+			a ^= nums[i]
+		} else {
+			b ^= nums[i]
+		}
+	}
+	return []int{a, b}
+}

+ 28 - 0
medium/264.ugly-number-ii.go

@@ -0,0 +1,28 @@
+func nthUglyNumber(n int) int {
+	nums := []int{1}
+	next2, next3, next5 := 2, 3, 5
+	for i, i2, i3, i5 := 1, 0, 0, 0; i < n; i++ {
+		next := next2
+		if next3 < next {
+			next = next3
+		}
+		if next5 < next {
+			next = next5
+		}
+		nums = append(nums, next)
+		if next == next2 {
+			i2++
+			next2 = nums[i2] * 2
+		}
+		if next == next3 {
+			i3++
+			next3 = nums[i3] * 3
+		}
+		if next == next5 {
+			i5++
+			next5 = nums[i5] * 5
+		}
+	}
+	return nums[n-1]
+}
+

+ 19 - 0
medium/274.h-index.go

@@ -0,0 +1,19 @@
+func hIndex(citations []int) int {
+	n := len(citations)
+	index := make([]int, n+1)
+	for _, c := range citations {
+		if n <= c {
+			index[n]++
+		} else {
+			index[c]++
+		}
+	}
+	for i := n; 1 <= i; i-- {
+		if i <= index[i] {
+			return i
+		}
+		index[i-1] += index[i]  // So smart! The citations of h is the accumulation of index[h]~index[n]
+	}
+	return 0
+}
+

+ 17 - 0
medium/275.h-index-ii.go

@@ -0,0 +1,17 @@
+func hIndex(citations []int) int {
+	// Target: find the first h that h <= citations[n-h]
+	n := len(citations)
+	beg, end := 0, n
+	for beg < end {
+		mid := beg + (end-beg)/2
+		h, citation := n-mid, citations[mid]
+		if h < citation {
+			end = mid
+		} else if citation < h {
+			beg = mid + 1
+		} else {
+			return h
+		}
+	}
+	return n - beg
+}

+ 19 - 0
medium/279.perfect-squares.go

@@ -0,0 +1,19 @@
+func numSquares(n int) int {
+	dp := make([]int, n+1)
+	dp[0] = 1000000
+	for i := 1; i < n+1; i *= 2 {
+		copy(dp[i:], dp[:i])
+	}
+	for i := 1; i*i <= n; i++ {
+		dp[i*i] = 1
+	}
+	for i := 1; i < n; i++ { // n(k) = n(i + j*j) = n(i) + 1
+		for j := 1; i+j*j <= n; j++ {
+			if dp[i]+1 < dp[i+j*j] {
+				dp[i+j*j] = dp[i] + 1
+			}
+		}
+	}
+	return dp[n]
+}
+

+ 32 - 0
medium/284.peeking-iterator.java

@@ -0,0 +1,32 @@
+// Java Iterator interface reference:
+// https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html
+class PeekingIterator implements Iterator<Integer> {
+	private Iterator<Integer> iter;
+	private Integer peek;
+
+	public PeekingIterator(Iterator<Integer> iterator) {
+	    // initialize any member here.
+	    this.iter = iterator;
+	}
+
+    // Returns the next element in the iteration without advancing the iterator.
+	public Integer peek() {
+		if (this.peek == null) this.peek = this.iter.next();
+		return this.peek;
+	}
+
+	// hasNext() and next() should behave the same as in the Iterator interface.
+	// Override them if needed.
+	@Override
+	public Integer next() {
+		if (this.peek == null) return this.iter.next();
+		Integer next = this.peek;
+		this.peek = null;
+		return next;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return peek != null || this.iter.hasNext();
+	}
+}

+ 19 - 0
medium/287.find-the-duplicate-number.go

@@ -0,0 +1,19 @@
+func findDuplicate(nums []int) int { // Binary search
+	n := len(nums)
+	beg, end := 1, n
+	for beg < end {
+		mid := (beg + end) / 2
+		cnt := 0
+		for i := 0; i < n; i++ {
+			if nums[i] <= mid {
+				cnt++
+			}
+		}
+		if cnt <= mid {
+			beg = mid + 1
+		} else {
+			end = mid
+		}
+	}
+	return beg
+}

+ 26 - 0
medium/289.game-of-life.go

@@ -0,0 +1,26 @@
+func gameOfLife(board [][]int) {
+	m, n := len(board), len(board[0])
+	xDir := []int{1, 1, 0, -1, -1, -1, 0, 1}
+	yDir := []int{0, -1, -1, -1, 0, 1, 1, 1}
+	for y := 0; y < m; y++ {
+		for x := 0; x < n; x++ {
+			cnt := 0
+			for i := 0; i < 8; i++ {
+				xPos, yPos := x+xDir[i], y+yDir[i]
+				if 0 <= xPos && xPos < n && 0 <= yPos && yPos < m {
+					cnt += board[yPos][xPos] & 1
+				}
+			}
+			if cnt == 2 {  // Keep current state
+				board[y][x] |= (board[y][x] & 1) << 1
+			} else if cnt == 3 {  // Live :-)
+				board[y][x] |= 2
+			}  // Else, die X-(
+		}
+	}
+	for y := 0; y < m; y++ {
+		for x := 0; x < n; x++ {
+			board[y][x] >>= 1
+		}
+	}
+}

+ 20 - 0
medium/299.bulls-and-cows.go

@@ -0,0 +1,20 @@
+func getHint(secret string, guess string) string {
+	s, g := make([]int, 10), make([]int, 10)
+	bulls, cows := 0, 0
+	for i := range secret {
+		if secret[i] == guess[i] {
+			bulls++
+		} else {
+			s[int(secret[i]-'0')]++
+			g[int(guess[i]-'0')]++
+		}
+	}
+	for i := 0; i < 10; i++ {
+		if s[i] < g[i] {
+			cows += s[i]
+		} else {
+			cows += g[i]
+		}
+	}
+	return fmt.Sprintf("%dA%dB", bulls, cows)
+}

+ 54 - 0
medium/300.longest-increasing-subsequence.go

@@ -0,0 +1,54 @@
+func lengthOfLISSlow(nums []int) int {
+	n := len(nums)
+	if n <= 1 {
+		return n
+	}
+	lis := make([]int, n) // DP, O(n^2) time complexity
+	lis[0] = 1
+	for i := 1; i < n; i *= 2 {
+		copy(lis[i:], lis[:i])
+	}
+	max := 1
+	for i := 1; i < n; i++ {
+		for j := 0; j < i; j++ {
+			if nums[j] < nums[i] && lis[i] < lis[j]+1 {
+				lis[i] = lis[j] + 1
+				if max < lis[i] {
+					max = lis[i]
+				}
+			}
+		}
+	}
+	return max
+}
+
+func lengthOfLIS(nums []int) int {
+	n := len(nums)
+	if n <= 1 {
+		return n
+	}
+	lis := []int{nums[0]}
+	max := 1
+	for i := 1; i < n; i++ {
+		if lis[max-1] < nums[i] {
+			lis = append(lis, nums[i]) // O(nlog(n)), maintain the smallest LIS only
+			max++
+		} else {
+			beg, end := 0, max
+			for beg < end {
+				mid := beg + (end-beg)/2
+				if lis[mid] < nums[i] {
+					beg = mid + 1
+				} else if nums[i] < lis[mid] {
+					end = mid
+				} else {
+					beg = mid
+					break
+				}
+			}
+			lis[beg] = nums[i]
+		}
+	}
+	return max
+}
+