邓心一 6 years ago
parent
commit
30e254d85d

+ 21 - 15
hard/282.expression-add-operators.go

@@ -1,30 +1,36 @@
-import (
-	"strconv"
-)
-
 func addOperators(num string, target int) (res []string) {
-	DFS(num, target, 0, "", 0, 0, &res)
+	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, target int, pos int, exp string, prev int, curr int, res *[]string) {
-	if pos == len(num) && curr == target {
-		*res = append(*res, exp)
+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
 	}
-	for i := pos; i < len(num); i++ {
+	n, i, l := 0, pos, length
+	if pos != 0 {
+		length++
+	}
+	for i < strlen {
 		if num[pos] == '0' && pos < i { // Avoid leading zero
 			break
 		}
-		str := num[pos:i+1]
-		n, _ := strconv.Atoi(str)
+		n = n*10 + int(num[i]-'0')
+		(*exp)[length] = num[i]
+		length, i = length+1, i+1
 		if pos == 0 { // Init DFS
-			DFS(num, target, i+1, str, n, n, res)
+			DFS(num, strlen, target, i, exp, length, n, n, res)
 			continue
 		}
-		DFS(num, target, i+1, exp+"+"+str, n, curr+n, res)
-		DFS(num, target, i+1, exp+"-"+str, -n, curr-n, res)
-		DFS(num, target, i+1, exp+"*"+str, prev*n, curr-prev+prev*n, res)
+		(*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();
+ */

+ 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]
+}
+

+ 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
+		}
+	}
+}