邓心一 7 年之前
父节点
当前提交
f9cdb1c52d
共有 30 个文件被更改,包括 1346 次插入12 次删除
  1. 77 0
      .vscode/c_cpp_properties.json
  2. 2 2
      easy/141.js
  3. 5 4
      easy/160.js
  4. 3 3
      easy/190.js
  5. 3 3
      easy/191.js
  6. 93 0
      medium/36.go
  7. 38 0
      medium/39.go
  8. 35 0
      medium/40.go
  9. 12 0
      medium/43.go
  10. 56 0
      medium/46.go
  11. 62 0
      medium/47.go
  12. 40 0
      medium/48.go
  13. 36 0
      medium/49.go
  14. 23 0
      medium/50.go
  15. 75 0
      medium/54.go
  16. 47 0
      medium/55.go
  17. 134 0
      medium/56.go
  18. 47 0
      medium/59.go
  19. 76 0
      medium/60.go
  20. 76 0
      medium/61.go
  21. 31 0
      medium/62.go
  22. 67 0
      medium/63.go
  23. 63 0
      medium/64.go
  24. 36 0
      medium/71.go
  25. 38 0
      medium/73.go
  26. 37 0
      medium/74.go
  27. 26 0
      medium/75.go
  28. 53 0
      medium/77.go
  29. 35 0
      medium/78.go
  30. 20 0
      medium/79.go

+ 77 - 0
.vscode/c_cpp_properties.json

@@ -0,0 +1,77 @@
+{
+    "configurations": [
+        {
+            "name": "Mac",
+            "includePath": [
+                "/usr/include",
+                "/usr/local/include",
+                "${workspaceRoot}"
+            ],
+            "defines": [],
+            "intelliSenseMode": "clang-x64",
+            "browse": {
+                "path": [
+                    "/usr/include",
+                    "/usr/local/include",
+                    "${workspaceRoot}"
+                ],
+                "limitSymbolsToIncludedHeaders": true,
+                "databaseFilename": ""
+            },
+            "macFrameworkPath": [
+                "/System/Library/Frameworks",
+                "/Library/Frameworks"
+            ]
+        },
+        {
+            "name": "Linux",
+            "includePath": [
+                "/usr/include",
+                "/usr/local/include",
+                "${workspaceRoot}"
+            ],
+            "defines": [],
+            "intelliSenseMode": "clang-x64",
+            "browse": {
+                "path": [
+                    "/usr/include",
+                    "/usr/local/include",
+                    "${workspaceRoot}"
+                ],
+                "limitSymbolsToIncludedHeaders": true,
+                "databaseFilename": ""
+            }
+        },
+        {
+            "name": "Win32",
+            "includePath": [
+                "C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.11.25503/include/*",
+                "C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.11.25503/atlmfc/include/*",
+                "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
+                "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
+                "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
+                "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
+                "${workspaceRoot}"
+            ],
+            "defines": [
+                "_DEBUG",
+                "UNICODE"
+            ],
+            "intelliSenseMode": "msvc-x64",
+            "browse": {
+                "path": [
+                    "C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.11.25503/include/*",
+                    "C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.11.25503/atlmfc/include/*",
+                    "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
+                    "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
+                    "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
+                    "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
+                    "${workspaceRoot}"
+                ],
+                "limitSymbolsToIncludedHeaders": true,
+                "databaseFilename": ""
+            }
+        }
+    ],
+    "version": 3
+}

+ 2 - 2
easy/141.js

@@ -15,7 +15,7 @@ function ListNode(val) {
  * @param {ListNode} head
  * @return {boolean}
  */
-var hasCycle = function(head) {
+var hasCycle = function (head) {
     if (head === null || head.next === null) return false
     let set = new Set()
     let curr = head
@@ -45,4 +45,4 @@ function __main__() {
     console.log(hasCycle(n2))
 }
 
-__main__()
+__main__()

+ 5 - 4
easy/160.js

@@ -16,9 +16,10 @@ function ListNode(val) {
  * @param {ListNode} headB
  * @return {ListNode}
  */
-var getIntersectionNode = function(headA, headB) {
+var getIntersectionNode = function (headA, headB) {
     let set = new Set()
-    let pA = headA, pB = headB
+    let pA = headA,
+        pB = headB
     while (pA !== null && pB != null) {
         if (set.has(pA)) return pA
         set.add(pA)
@@ -56,9 +57,9 @@ function __main__() {
     n1.next = n12
     n12.next = n13
     n24.next = n12
-    let n3 = new ListNode(3)    
+    let n3 = new ListNode(3)
     console.log(getIntersectionNode(n1, n2))
     console.log(getIntersectionNode(n2, n3))
 }
 
-__main__()
+__main__()

+ 3 - 3
easy/190.js

@@ -2,7 +2,7 @@
  * @param {number} n - a positive integer
  * @return {number} - a positive integer
  */
-var reverseBitsOld = function(n) {
+var reverseBitsOld = function (n) {
     let res = 0
     let last
     for (let i = 0; i < 32; i++) {
@@ -15,7 +15,7 @@ var reverseBitsOld = function(n) {
 };
 
 // [note] in js, signed -> unsigned: n >>> 0
-var reverseBits = function(n) {  
+var reverseBits = function (n) {
     for (let i = 0, j = 31; i <= j; i++, j--) {
         let bit = (1 << i & n) >>> i ^ (1 << j & n) >>> j
         n ^= bit << j
@@ -33,4 +33,4 @@ function __main__() {
     console.log(reverseBitsOld(1))
 }
 
-__main__()
+__main__()

+ 3 - 3
easy/191.js

@@ -2,14 +2,14 @@
  * @param {number} n - a positive integer
  * @return {number}
  */
-var hammingWeightOld = function(n) {
+var hammingWeightOld = function (n) {
     let res = 0
     for (let i = 0; i < 32; i++, res += n & 1, n >>= 1) {}
     return res
 };
 
 // simple solution using build-in
-var hammingWeight = function(n) {
+var hammingWeight = function (n) {
     return (n).toString(2).replace(/0/g, '').length;
 };
 
@@ -18,4 +18,4 @@ function __main__() {
     console.log(hammingWeightOld(0xFFFFFFFF))
 }
 
-__main__()
+__main__()

+ 93 - 0
medium/36.go

@@ -0,0 +1,93 @@
+package main
+
+import (
+	"fmt"
+)
+
+// 1 -> has this value
+var mDigit = map[byte]uint{
+	'.': 0x000,
+	'1': 0x100,
+	'2': 0x080,
+	'3': 0x040,
+	'4': 0x020,
+	'5': 0x010,
+	'6': 0x008,
+	'7': 0x004,
+	'8': 0x002,
+	'9': 0x001,
+}
+
+// if sudoku is solvable, return true
+func isValidSudokuOld(board [][]byte) bool {
+	const ROW, COL, BLOCK = 0, 1, 2
+	arr := [3][9]uint{}
+	for i, row := range board {
+		for j, v := range row {
+			if arr[ROW][i]&mDigit[v] > 0 {
+				return false
+			}
+			arr[ROW][i] |= mDigit[v]
+			if arr[COL][j]&mDigit[v] > 0 {
+				return false
+			}
+			arr[COL][j] |= mDigit[v]
+			idx := i/3*3 + j/3
+			if arr[BLOCK][idx]&mDigit[v] > 0 {
+				return false
+			}
+			arr[BLOCK][idx] |= mDigit[v]
+		}
+	}
+	for i, row := range board {
+		for j, v := range row {
+			mask := ^mDigit[v]
+			flag := 0x1FF ^ (arr[ROW][i] & mask)
+			flag &= 0x1FF ^ (arr[COL][j] & mask)
+			idx := i/3*3 + j/3
+			flag &= 0x1FF ^ (arr[BLOCK][idx] & mask)
+			if flag == 0 {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+func isValidSudoku(board [][]byte) bool {
+	const ROW, COL, BLOCK = 0, 1, 2
+	arr := [3][9]uint{}
+	for i, row := range board {
+		for j, v := range row {
+			if arr[ROW][i]&mDigit[v] > 0 {
+				return false
+			}
+			arr[ROW][i] |= mDigit[v]
+			if arr[COL][j]&mDigit[v] > 0 {
+				return false
+			}
+			arr[COL][j] |= mDigit[v]
+			idx := i/3*3 + j/3
+			if arr[BLOCK][idx]&mDigit[v] > 0 {
+				return false
+			}
+			arr[BLOCK][idx] |= mDigit[v]
+		}
+	}
+	return true
+}
+
+func main() {
+	b1 := [][]byte{
+		{'.', '8', '7', '6', '5', '4', '3', '2', '1'},
+		{'2', '.', '.', '.', '.', '.', '.', '.', '.'},
+		{'3', '.', '.', '.', '.', '.', '.', '.', '.'},
+		{'4', '.', '.', '.', '.', '.', '.', '.', '.'},
+		{'5', '.', '.', '.', '.', '.', '.', '.', '.'},
+		{'6', '.', '.', '.', '.', '.', '.', '.', '.'},
+		{'7', '.', '.', '.', '.', '.', '.', '.', '.'},
+		{'8', '.', '.', '.', '.', '.', '.', '.', '.'},
+		{'9', '.', '.', '.', '.', '.', '.', '.', '.'},
+	}
+	fmt.Println(isValidSudoku(b1))
+}

+ 38 - 0
medium/39.go

@@ -0,0 +1,38 @@
+package main
+
+import (
+	"fmt"
+	"sort"
+)
+
+func combinationSumIter(candidates []int, target int, beg int, last []int, res *[][]int) {
+	if target == 0 {
+		*res = append(*res, last)
+	}
+	for i := beg; i < len(candidates) && candidates[i] <= target; i++ {
+		// if don't copy solution, iteration'll fail
+		// go slice is just like a ptr
+		solution := make([]int, len(last))
+		copy(solution, last)
+		solution = append(solution, candidates[i])
+		combinationSumIter(candidates, target-candidates[i], i, solution, res)
+	}
+}
+
+func combinationSum(candidates []int, target int) [][]int {
+	res := make([][]int, 0)
+	sort.Ints(candidates)
+	combinationSumIter(candidates, target, 0, []int{}, &res)
+	return res
+}
+
+func main() {
+	a1 := []int{2, 3, 6, 7}
+	fmt.Println(combinationSum(a1, 7))
+	a2 := []int{1, 2}
+	fmt.Println(combinationSum(a2, 4))
+	a3 := []int{8, 7, 4, 3}
+	fmt.Println(combinationSum(a3, 11))
+	a4 := []int{7, 3, 2}
+	fmt.Println(combinationSum(a4, 18))
+}

+ 35 - 0
medium/40.go

@@ -0,0 +1,35 @@
+package main
+
+import (
+	"fmt"
+	"sort"
+)
+
+func combinationSum2Iter(candidates []int, target int, last []int, beg int, res *[][]int) {
+	if target == 0 {
+		*res = append(*res, last)
+		return
+	}
+	for i := beg; i < len(candidates) && candidates[i] <= target; i++ {
+		// method to remove duplicated solutions
+		if i > beg && candidates[i] == candidates[i-1] {
+			continue
+		}
+		solution := make([]int, len(last))
+		copy(solution, last)
+		solution = append(solution, candidates[i])
+		combinationSum2Iter(candidates, target-candidates[i], solution, i+1, res)
+	}
+}
+
+func combinationSum2(candidates []int, target int) [][]int {
+	res := make([][]int, 0)
+	sort.Ints(candidates)
+	combinationSum2Iter(candidates, target, []int{}, 0, &res)
+	return res
+}
+
+func main() {
+	a1 := []int{10, 1, 2, 7, 6, 1, 5}
+	fmt.Println(combinationSum2(a1, 8))
+}

+ 12 - 0
medium/43.go

@@ -0,0 +1,12 @@
+package main
+
+func multiply(num1 string, num2 string) string {
+	i, j := len(num1)-1, len(num2)
+	for ; ; i, j = i-1, j-1 {
+
+	}
+}
+
+func main() {
+
+}

+ 56 - 0
medium/46.go

@@ -0,0 +1,56 @@
+package main
+
+import (
+	"fmt"
+)
+
+func nextPermutation(nums []int) {
+	if len(nums) < 2 {
+		return
+	}
+	// rfind first num descended 'ni'
+	// 346987521 -> 34 '6' 987521
+	i := len(nums) - 2
+	for ; i >= 0 && nums[i] >= nums[i+1]; i-- {
+	}
+	if i != -1 {
+		// find the last num 'nj' which is larger than 'ni'
+		// swap 'nj', 'ni'
+		// 34 '6' 987521 -> 34 '6' 98 '7' 521 -> 34 '7' 98 '6' 521
+		j := i + 1
+		for ; j+1 < len(nums) && nums[j+1] > nums[i]; j++ {
+		}
+		nums[i], nums[j] = nums[j], nums[i]
+	}
+	// reverse the sequence after pos 'i'
+	// 34 '7' '986521' -> 34 '7' '125689'
+	for l, r := i+1, len(nums)-1; l < r; l, r = l+1, r-1 {
+		nums[l], nums[r] = nums[r], nums[l]
+	}
+}
+
+func permute(nums []int) [][]int {
+	if len(nums) == 0 {
+		return [][]int{}
+	}
+	cnt := 1
+	for i := 2; i <= len(nums); i++ {
+		cnt *= i
+	}
+	res := [][]int{nums}
+	last := make([]int, len(nums))
+	copy(last, nums)
+	for i := 0; i < cnt-1; i++ {
+		solution := make([]int, len(last))
+		copy(solution, last)
+		nextPermutation(solution)
+		copy(last, solution)
+		res = append(res, solution)
+	}
+	return res
+}
+
+func main() {
+	a1 := []int{1, 2, 3}
+	fmt.Println(permute(a1))
+}

+ 62 - 0
medium/47.go

@@ -0,0 +1,62 @@
+package main
+
+import "fmt"
+
+func nextPermutation(nums []int) {
+	if len(nums) < 2 {
+		return
+	}
+	// rfind first num descended 'ni'
+	// 346987521 -> 34 '6' 987521
+	i := len(nums) - 2
+	for ; i >= 0 && nums[i] >= nums[i+1]; i-- {
+	}
+	if i != -1 {
+		// find the last num 'nj' which is larger than 'ni'
+		// swap 'nj', 'ni'
+		// 34 '6' 987521 -> 34 '6' 98 '7' 521 -> 34 '7' 98 '6' 521
+		j := i + 1
+		for ; j+1 < len(nums) && nums[j+1] > nums[i]; j++ {
+		}
+		nums[i], nums[j] = nums[j], nums[i]
+	}
+	// reverse the sequence after pos 'i'
+	// 34 '7' '986521' -> 34 '7' '125689'
+	for l, r := i+1, len(nums)-1; l < r; l, r = l+1, r-1 {
+		nums[l], nums[r] = nums[r], nums[l]
+	}
+}
+
+func isEqual(a, b []int) bool {
+	for i, v := range b {
+		if a[i] != v {
+			return false
+		}
+	}
+	return true
+}
+
+func permuteUnique(nums []int) [][]int {
+	if len(nums) == 0 {
+		return [][]int{}
+	}
+	res := [][]int{nums}
+	last := make([]int, len(nums))
+	copy(last, nums)
+	for {
+		solution := make([]int, len(last))
+		copy(solution, last)
+		nextPermutation(solution)
+		if isEqual(nums, solution) {
+			break
+		}
+		copy(last, solution)
+		res = append(res, solution)
+	}
+	return res
+}
+
+func main() {
+	a1 := []int{1, 1, 2, 3}
+	fmt.Println(permuteUnique(a1))
+}

+ 40 - 0
medium/48.go

@@ -0,0 +1,40 @@
+package main
+
+import (
+	"fmt"
+)
+
+/**
+ * '1' 2 '3'  swap   '7' 2 '1'  next   7 '2' 1
+ *  4  5  6  ----->   4  5  6  -----> '4' 5 '6' -> ...
+ * '7' 8 '9'         '9' 8 '3'         9 '8' 3
+ */
+func rotate(matrix [][]int) {
+	side := len(matrix) - 1
+	for i := 0; i <= side/2; i++ {
+		for j := 0; j < side-2*i; j++ {
+			matrix[i][i+j], matrix[i+j][side-i], matrix[side-i][side-i-j], matrix[side-i-j][i] = matrix[side-i-j][i], matrix[i][i+j], matrix[i+j][side-i], matrix[side-i][side-i-j]
+		}
+	}
+}
+
+func main() {
+	m1 := [][]int{
+		{11, 22, 33, 44, 55},
+		{16, 27, 38, 49, 50},
+		{11, 23, 35, 47, 59},
+		{12, 24, 36, 48, 50},
+		{15, 24, 33, 42, 51},
+	}
+	rotate(m1)
+	fmt.Println(m1)
+	m2 := [][]int{
+		{1, 2},
+		{3, 4},
+	}
+	rotate(m2)
+	fmt.Println(m2)
+	m3 := [][]int{}
+	rotate(m3)
+	fmt.Println(m3)
+}

+ 36 - 0
medium/49.go

@@ -0,0 +1,36 @@
+package main
+
+import (
+	"fmt"
+	"sort"
+)
+
+// RuneSlice implements sort.Interface
+type RuneSlice []rune
+
+func (p RuneSlice) Len() int           { return len(p) }
+func (p RuneSlice) Less(i, j int) bool { return p[i] < p[j] }
+func (p RuneSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func groupAnagrams(strs []string) (res [][]string) {
+	// sorted str : index
+	m := map[string]int{}
+	for _, v := range strs {
+		runes := []rune(v)
+		sort.Sort([]int(runes))
+		if idx, ok := m[string(runes)]; !ok {
+			m[string(runes)] = len(m)
+			res = append(res, []string{v})
+		} else {
+			res[idx] = append(res[idx], v)
+		}
+	}
+	return res
+}
+
+func main() {
+	a1 := []string{"eat", "tea", "tan", "ate", "nat", "bat"}
+	fmt.Println(groupAnagrams(a1))
+	a2 := []string{}
+	fmt.Println(groupAnagrams(a2))
+}

+ 23 - 0
medium/50.go

@@ -0,0 +1,23 @@
+package main
+
+import (
+	"fmt"
+)
+
+func myPow(x float64, n int) float64 {
+	if n < 0 {
+		n = -n
+		x = 1 / x
+	}
+	res := 1.0
+	for base := x; n > 0; base, n = base*base, n>>1 {
+		if n&1 == 1 {
+			res *= base
+		}
+	}
+	return res
+}
+
+func main() {
+	fmt.Println(myPow(2.0, -10))
+}

+ 75 - 0
medium/54.go

@@ -0,0 +1,75 @@
+package main
+
+import (
+	"fmt"
+)
+
+func spiralOrder(matrix [][]int) (res []int) {
+	if len(matrix) == 0 {
+		return
+	}
+	w, h := len(matrix[0]), len(matrix)
+	for x, y := 0, 0; w > 0 && h > 0; w, h, x, y = w-2, h-2, x+1, y+1 {
+		if h == 1 {
+			// 1 2 3 4
+			res = append(res, matrix[y][x:x+w]...)
+			return
+		} else if w == 1 {
+			// 1
+			// 2
+			// 3
+			// 4
+			for i := 0; i < h; i, y = i+1, y+1 {
+				res = append(res, matrix[y][x])
+			}
+			return
+		}
+		// 1   2   3   4  loop1 -> 1  2  3
+		// 12   ...    5  loop2 -> 4  5  6
+		// 11   ...    6  loop3 -> 7  8  9
+		// 10  9   8   7  loop4 -> 10 11 12
+		var xSpeed, ySpeed, length int
+		for loop := 0; loop < 4; loop++ {
+			switch loop {
+			case 0:
+				xSpeed, ySpeed, length = 1, 0, w-1
+			case 1:
+				xSpeed, ySpeed, length = 0, 1, h-1
+			case 2:
+				xSpeed, ySpeed, length = -1, 0, w-1
+			default:
+				xSpeed, ySpeed, length = 0, -1, h-1
+			}
+			for i := 0; i < length; i++ {
+				res = append(res, matrix[y][x])
+				x += xSpeed
+				y += ySpeed
+			}
+		}
+	}
+	return
+}
+
+func main() {
+	m1 := [][]int{
+		{11, 22, 33, 44, 55},
+		{16, 27, 38, 49, 50},
+		{11, 23, 35, 47, 59},
+		{12, 24, 36, 48, 50},
+		{15, 24, 33, 42, 51},
+	}
+	fmt.Println(spiralOrder(m1))
+	m2 := [][]int{
+		{11, 22, 11},
+		{16, 27, 33},
+		{11, 23, 24},
+		{12, 13, 44},
+	}
+	fmt.Println(spiralOrder(m2))
+	m3 := [][]int{
+		{11},
+		{16},
+		{11},
+	}
+	fmt.Println(spiralOrder(m3))
+}

+ 47 - 0
medium/55.go

@@ -0,0 +1,47 @@
+package main
+
+func canJumpIter(nums []int, visited map[int]bool, pos int) bool {
+	if visited[pos] {
+		return false
+	}
+	visited[pos] = true
+	if pos+nums[pos] >= len(nums)-1 {
+		return true
+	}
+	if nums[pos] == 0 {
+		return false
+	}
+	for i := 1; i <= nums[pos]; i++ {
+		if canJumpIter(nums, visited, pos+i) {
+			return true
+		}
+	}
+	return false
+}
+
+// TLE
+func canJumpOld(nums []int) bool {
+	return canJumpIter(nums, map[int]bool{}, 0)
+}
+
+func canJump(nums []int) bool {
+	// leap: the longest distance of jumping at idx 'i'
+	for i, leap := 0, 0; i < len(nums); i, leap = i+1, leap-1 {
+		if leap < 0 {
+			return false
+		}
+		if nums[i] > leap {
+			leap = nums[i]
+		}
+	}
+	return true
+}
+
+func main() {
+	a1 := []int{2, 3, 1, 1, 4}
+	a2 := []int{3, 2, 1, 0, 4}
+	a3 := []int{0}
+	fmt.Println(canJump(a1))
+	fmt.Println(canJump(a2))
+	fmt.Println(canJump(a3))
+}

+ 134 - 0
medium/56.go

@@ -0,0 +1,134 @@
+package main
+
+import (
+	"fmt"
+	"sort"
+)
+
+// Interval ...
+type Interval struct {
+	Start int
+	End   int
+}
+
+// Endpoint ...
+type Endpoint struct {
+	Val   int
+	IsEnd bool
+}
+
+// PointSlice ...
+type PointSlice []Endpoint
+
+func (p PointSlice) Len() int { return len(p) }
+func (p PointSlice) Less(i, j int) bool {
+	// 1( 4) 4( 6) -> 1( 4( 4) 6)
+	// important!
+	if p[i].Val == p[j].Val {
+		return p[j].IsEnd
+	}
+	return p[i].Val < p[j].Val
+}
+func (p PointSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+/**
+ * Definition for an interval.
+ * type Interval struct {
+ *	   Start int
+ *	   End   int
+ * }
+ */
+func mergeOld(intervals []Interval) (res []Interval) {
+	points := []Endpoint{}
+	for _, v := range intervals {
+		points = append(points, Endpoint{v.Start, false})
+		points = append(points, Endpoint{v.End, true})
+	}
+	sort.Sort(PointSlice(points))
+	for i, cnt := 0, 0; i < len(points); i++ {
+		if cnt == 0 {
+			inter := Interval{points[i].Val, 0}
+			res = append(res, inter)
+		}
+		if !points[i].IsEnd {
+			cnt++
+		} else {
+			cnt--
+			if cnt == 0 {
+				res[len(res)-1].End = points[i].Val
+			}
+		}
+
+	}
+	return
+}
+
+// By : by which function to sort intervals
+type By func(p, q *Interval) bool
+
+// IntervalSorter : interface for sorting intervals
+type IntervalSorter struct {
+	intervals []Interval
+	by        By
+}
+
+func (p *IntervalSorter) Len() int {
+	return len(p.intervals)
+}
+func (p *IntervalSorter) Less(i, j int) bool {
+	return p.by(&p.intervals[i], &p.intervals[j])
+}
+func (p *IntervalSorter) Swap(i, j int) {
+	p.intervals[i], p.intervals[j] = p.intervals[j], p.intervals[i]
+}
+
+// Sort : usage: By(func).Sort(intervals)
+func (by By) Sort(intervals []Interval) {
+	is := &IntervalSorter{intervals, by}
+	sort.Sort(is)
+}
+
+func startValue(p, q *Interval) bool {
+	return p.Start < q.Start
+}
+
+func maxInt(x, y int) int {
+	if x > y {
+		return x
+	}
+	return y
+}
+
+/**
+ * Definition for an interval.
+ * type Interval struct {
+ *	   Start int
+ *	   End   int
+ * }
+ */
+func merge(intervals []Interval) (res []Interval) {
+	if len(intervals) < 2 {
+		return intervals
+	}
+	By(startValue).Sort(intervals)
+	res = append(res, intervals[0])
+	for i := 1; i < len(intervals); i++ {
+		if intervals[i].Start > res[len(res)-1].End {
+			res = append(res, intervals[i])
+			continue
+		}
+		res[len(res)-1].End = maxInt(intervals[i].End, res[len(res)-1].End)
+	}
+	return
+}
+
+func main() {
+	i1 := []Interval{{1, 3}, {2, 6}, {8, 10}, {15, 18}}
+	i2 := []Interval{}
+	i3 := []Interval{{1, 4}, {4, 5}, {5, 6}}
+	i4 := []Interval{{1, 4}, {0, 1}}
+	fmt.Println(merge(i1))
+	fmt.Println(merge(i2))
+	fmt.Println(merge(i3))
+	fmt.Println(merge(i4))
+}

+ 47 - 0
medium/59.go

@@ -0,0 +1,47 @@
+package main
+
+import (
+	"fmt"
+)
+
+func generateMatrix(n int) [][]int {
+	res := make([][]int, n)
+	for i := range res {
+		res[i] = make([]int, n)
+	}
+	cnt := 1
+	x, y := 0, 0
+	for l := n; l > 0; l -= 2 {
+		if l == 1 {
+			res[y][x] = cnt
+			return res
+		}
+		for dir := 0; dir < 4; dir++ {
+			var xSpeed, ySpeed int
+			switch dir {
+			case 0:
+				xSpeed, ySpeed = 1, 0
+			case 1:
+				xSpeed, ySpeed = 0, 1
+			case 2:
+				xSpeed, ySpeed = -1, 0
+			default:
+				xSpeed, ySpeed = 0, -1
+			}
+			for i := 0; i < l-1; i, cnt = i+1, cnt+1 {
+				res[y][x] = cnt
+				x, y = x+xSpeed, y+ySpeed
+			}
+		}
+		x, y = x+1, y+1
+	}
+	return res
+}
+
+func main() {
+	fmt.Println(generateMatrix(0))
+	fmt.Println(generateMatrix(1))
+	fmt.Println(generateMatrix(2))
+	fmt.Println(generateMatrix(3))
+	fmt.Println(generateMatrix(4))
+}

+ 76 - 0
medium/60.go

@@ -0,0 +1,76 @@
+package main
+
+import (
+	"fmt"
+)
+
+func nextPermutation(runes []rune) {
+	if len(runes) < 2 {
+		return
+	}
+	var i int
+	for i = len(runes) - 2; i >= 0; i-- {
+		if runes[i] < runes[i+1] {
+			break
+		}
+	}
+	if i != -1 {
+		var j int
+		for j = i; j < len(runes)-1 && runes[j+1] > runes[i]; j++ {
+		}
+		runes[i], runes[j] = runes[j], runes[i]
+	}
+	for j, k := i+1, len(runes)-1; j < k; j, k = j+1, k-1 {
+		runes[j], runes[k] = runes[k], runes[j]
+	}
+}
+
+func getPermutationOld(n int, k int) string {
+	res := make([]rune, 0)
+	for i := 1; i <= n; i++ {
+		res = append(res, rune('0'+i))
+	}
+	for i := 1; i < k; i++ {
+		nextPermutation(res)
+	}
+	return string(res)
+}
+
+// (1 2 3 4) -> 4! permutaion
+// 1 (2 3 4) -> 3! permutaion
+// get 16th permutaion => 16 - 1 > 3! + 3!, so 3 (1 2 4)
+// => 15 - 3! - 3! = 3 > 2!, so 3 2 (1 4)
+// => 1, so 3 2 4 (1) => (append last candidate) 3 2 4 1
+func getPermutation(n int, k int) string {
+	res := make([]byte, 0)
+	candidate := make([]byte, 0)
+	for i := 0; i < n; i++ {
+		candidate = append(candidate, byte('1'+i))
+	}
+	// k: the No. of permutation
+	// k--: steps left to next permutation
+	k--
+	for i, base := n-1, fact(n-1); i > 0; i-- {
+		idx := k / base
+		res = append(res, candidate[idx])
+		candidate = append(candidate[:idx], candidate[idx+1:]...)
+		k -= idx * base
+		base /= i
+	}
+	res = append(res, candidate...)
+	return string(res)
+}
+
+func fact(x int) int {
+	if x <= 1 {
+		return 1
+	}
+	return x * fact(x-1)
+}
+
+func main() {
+	fmt.Println(getPermutationOld(4, 16))
+	fmt.Println(getPermutation(4, 16))
+	fmt.Println(getPermutation(1, 16))
+	fmt.Println(getPermutation(0, 16))
+}

+ 76 - 0
medium/61.go

@@ -0,0 +1,76 @@
+package main
+
+import (
+	"fmt"
+)
+
+// ListNode ...
+type ListNode struct {
+	Val  int
+	Next *ListNode
+}
+
+func list2str(head *ListNode) string {
+	curr := head
+	str := make([]rune, 0)
+	for curr != nil {
+		str = append(str, rune(curr.Val+'0'))
+		curr = curr.Next
+	}
+	return string(str)
+}
+
+/**
+ * Definition for singly-linked list.
+ * type ListNode struct {
+ *     Val int
+ *     Next *ListNode
+ * }
+ */
+func rotateRight(head *ListNode, k int) *ListNode {
+	if head == nil || head.Next == nil {
+		return head
+	}
+	dummy := ListNode{0, head}
+	curr := &dummy
+	length := 0
+	for curr.Next != nil {
+		curr = curr.Next
+		length++
+	}
+	k %= length
+	if k == 0 {
+		return dummy.Next
+	}
+	fast := &dummy
+	curr = &dummy
+	for i := 0; i < k; i++ {
+		fast = fast.Next
+	}
+	for fast.Next != nil {
+		fast = fast.Next
+		curr = curr.Next
+	}
+	fast.Next = dummy.Next
+	dummy.Next = curr.Next
+	curr.Next = nil
+	return dummy.Next
+}
+
+func main() {
+	l16 := ListNode{6, nil}
+	l15 := ListNode{5, &l16}
+	l14 := ListNode{4, &l15}
+	l13 := ListNode{3, &l14}
+	l12 := ListNode{2, &l13}
+	l1 := &ListNode{1, &l12}
+	fmt.Println(list2str(l1))
+	fmt.Println(list2str(rotateRight(l1, 0)))
+	fmt.Println(list2str(rotateRight(l1, 1)))
+	fmt.Println(list2str(rotateRight(&l16, 2)))
+	fmt.Println(list2str(rotateRight(&l14, 3)))
+	fmt.Println(list2str(rotateRight(l1, 4)))
+	fmt.Println(list2str(rotateRight(&l13, 5)))
+	fmt.Println(list2str(rotateRight(&l14, 6)))
+	fmt.Println(list2str(rotateRight(&l14, 7)))
+}

+ 31 - 0
medium/62.go

@@ -0,0 +1,31 @@
+package main
+
+import (
+	"fmt"
+)
+
+func uniquePaths(m int, n int) int {
+	if m == 1 || n == 1 {
+		return 1
+	}
+	grid := make([][]int, m)
+	for i := range grid {
+		grid[i] = make([]int, n)
+		grid[i][0] = 1
+	}
+	for i := range grid[0] {
+		grid[0][i] = 1
+	}
+	for i := 1; i < m; i++ {
+		for j := 1; j < n; j++ {
+			grid[i][j] = grid[i-1][j] + grid[i][j-1]
+		}
+	}
+	return grid[m-1][n-1]
+}
+
+func main() {
+	fmt.Println(uniquePaths(1, 1))
+	fmt.Println(uniquePaths(1, 2))
+	fmt.Println(uniquePaths(3, 7))
+}

+ 67 - 0
medium/63.go

@@ -0,0 +1,67 @@
+package main
+
+import (
+	"fmt"
+)
+
+func uniquePathsWithObstacles(obstacleGrid [][]int) int {
+	m, n := len(obstacleGrid), len(obstacleGrid[0])
+	// only one row/col
+	if m == 1 || n == 1 {
+		for i := 0; i < m; i++ {
+			for j := 0; j < n; j++ {
+				if obstacleGrid[i][j] == 1 {
+					return 0
+				}
+			}
+		}
+		return 1
+	}
+	grid := make([][]int, m)
+	grid[0] = make([]int, n)
+	if obstacleGrid[0][0] == 1 {
+		return 0
+	}
+	grid[0][0] = 1
+	// first row
+	for i := 1; i < n; i++ {
+		if obstacleGrid[0][i] == 1 {
+			break
+		}
+		grid[0][i] = 1
+	}
+	// first col
+	for i := 1; i < m; i++ {
+		grid[i] = make([]int, n)
+		if obstacleGrid[i][0] == 1 {
+			grid[i][0] = 0
+			continue
+		}
+		grid[i][0] = grid[i-1][0]
+	}
+	for i := 1; i < m; i++ {
+		for j := 1; j < n; j++ {
+			if obstacleGrid[i][j] == 1 {
+				grid[i][j] = 0
+			} else {
+				grid[i][j] = grid[i-1][j] + grid[i][j-1]
+			}
+		}
+	}
+	return grid[m-1][n-1]
+}
+
+func main() {
+	o1 := [][]int{
+		{0, 0, 0},
+		{0, 1, 0},
+		{0, 0, 0},
+	}
+	fmt.Println(uniquePathsWithObstacles(o1))
+	o2 := [][]int{
+		{0, 0, 1},
+		{0, 0, 0},
+		{0, 0, 0},
+	}
+	fmt.Println(uniquePathsWithObstacles(o2))
+}

+ 63 - 0
medium/64.go

@@ -0,0 +1,63 @@
+package main
+
+import (
+	"fmt"
+)
+
+func minInt(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+func minPathSumOld(grid [][]int) int {
+	m, n := len(grid), len(grid[0])
+	minGrid := make([][]int, m)
+	// 1st col
+	for i, sum := 0, 0; i < m; i++ {
+		minGrid[i] = make([]int, n)
+		sum += grid[i][0]
+		minGrid[i][0] = sum
+	}
+	// 1st row
+	for i, sum := 1, grid[0][0]; i < n; i++ {
+		sum += grid[0][i]
+		minGrid[0][i] = sum
+	}
+	for i := 1; i < m; i++ {
+		for j := 1; j < n; j++ {
+			minGrid[i][j] = grid[i][j] + minInt(minGrid[i-1][j], minGrid[i][j-1])
+		}
+	}
+	fmt.Println(minGrid)
+	return minGrid[m-1][n-1]
+}
+
+func minPathSum(grid [][]int) int {
+	// no need to create a new minGrid!
+	m, n := len(grid), len(grid[0])
+	// 1st col
+	for i := 1; i < m; i++ {
+		grid[i][0] += grid[i-1][0]
+	}
+	// 1st row
+	for i := 1; i < n; i++ {
+		grid[0][i] += grid[0][i-1]
+	}
+	for i := 1; i < m; i++ {
+		for j := 1; j < n; j++ {
+			grid[i][j] += minInt(grid[i-1][j], grid[i][j-1])
+		}
+	}
+	return grid[m-1][n-1]
+}
+
+func main() {
+	g1 := [][]int{
+		{1, 3, 1},
+		{1, 5, 1},
+		{4, 2, 1},
+	}
+	fmt.Println(minPathSum(g1))
+}

+ 36 - 0
medium/71.go

@@ -0,0 +1,36 @@
+package main
+
+import (
+	"fmt"
+	"strings"
+)
+
+func simplifyPath(path string) string {
+	strs := strings.Split(path, "/")
+	res := []string{""}
+	for _, v := range strs {
+		// "/./" or "//" => ""
+		if v == "." || v == "" {
+		} else if v == ".." {
+			// "/../" => "/"
+			// "/d/c/../" => "/d"
+			if len(res) != 1 {
+				res = res[:len(res)-1]
+			}
+		} else {
+			// "/c" => "/c"
+			res = append(res, v)
+		}
+	}
+	// "" => "/"
+	if len(res) == 1 {
+		return "/"
+	}
+	return strings.Join(res, "/")
+}
+
+func main() {
+	fmt.Println(simplifyPath("/c/"))
+	fmt.Println(simplifyPath("/a/./b/../../c/"))
+	fmt.Println(simplifyPath("/../../"))
+}

+ 38 - 0
medium/73.go

@@ -0,0 +1,38 @@
+package main
+
+import (
+	"fmt"
+)
+
+func setZeroes(matrix [][]int) {
+	// Can use type 'map[int]struct{}' instead,
+	// and insert empty struct like 'struct{}{}'.
+	// Use 'if _, ok := m[key]; ok {}' to check.
+	rows, cols := map[int]bool{}, map[int]bool{}
+	for y, row := range matrix {
+		for x, v := range row {
+			if v == 0 {
+				rows[y] = true
+				cols[x] = true
+			}
+		}
+	}
+	for y, row := range matrix {
+		for x := range row {
+			if cols[x] || rows[y] {
+				matrix[y][x] = 0
+			}
+		}
+	}
+}
+
+func main() {
+	m1 := [][]int{
+		{0, 2, 4, 6},
+		{1, 3, 4, 5},
+		{6, 4, 0, 7},
+		{4, 8, 9, 3},
+	}
+	setZeroes(m1)
+	fmt.Println(m1)
+}

+ 37 - 0
medium/74.go

@@ -0,0 +1,37 @@
+package main
+
+import (
+	"fmt"
+)
+
+func searchMatrix(matrix [][]int, target int) bool {
+	if len(matrix) == 0 || len(matrix[0]) == 0 {
+		return false
+	}
+	m, n := len(matrix), len(matrix[0])
+	beg, end := 0, m*n-1
+	for beg <= end {
+		mid := (beg + end) / 2
+		midVal := matrix[mid/n][mid%n]
+		if target > midVal {
+			beg = mid + 1
+		} else if target < midVal {
+			end = mid - 1
+		} else {
+			return true
+		}
+	}
+	return false
+}
+
+func main() {
+	m1 := [][]int{
+		{1, 3, 6, 8},
+		{9, 13, 53, 76},
+		{99, 123, 243, 453},
+		{654, 765, 876, 987},
+	}
+	fmt.Println(searchMatrix(m1, 987))
+	fmt.Println(searchMatrix(m1, 97))
+	fmt.Println(searchMatrix(m1, 1))
+}

+ 26 - 0
medium/75.go

@@ -0,0 +1,26 @@
+package main
+
+import (
+	"fmt"
+)
+
+// ?? check the best solution the next time
+func sortColors(nums []int) {
+	mCnt := [3]int{}
+	for _, v := range nums {
+		mCnt[v]++
+	}
+	for idx, color := 0, 0; color < 3; color++ {
+		cnt := mCnt[color]
+		for i := 0; i < cnt; idx, i = idx+1, i+1 {
+			nums[idx] = color
+		}
+	}
+}
+
+func main() {
+	c1 := []int{0, 1, 1, 2, 0, 0, 1, 2, 1}
+	sortColors(c1)
+	fmt.Println(c1)
+	sortColors([]int{})
+}

+ 53 - 0
medium/77.go

@@ -0,0 +1,53 @@
+package main
+
+import (
+	"fmt"
+)
+
+func combinIter(n int, k int, last []int, res *[][]int) {
+	solution := make([]int, len(last))
+	copy(solution, last)
+	if k == 0 {
+		*res = append(*res, solution)
+		return
+	}
+	var i int
+	if len(solution) != 0 {
+		i = solution[len(solution)-1] + 1
+	} else {
+		i = 1
+	}
+	for ; i <= n; i++ {
+		combinIter(n, k-1, append(solution, i), res)
+	}
+}
+
+func combineOld(n int, k int) (res [][]int) {
+	combinIter(n, k, []int{}, &res)
+	return
+}
+
+// a cleaner way of recursion
+func combine(n int, k int) (res [][]int) {
+	// Cnn or C0n
+	if n == k || k == 0 {
+		row := make([]int, k)
+		for i := range row {
+			row[i] = i + 1
+		}
+		return append(res, row)
+	}
+	// C(k)(n) = C(k-1)(n-1) + C(k)(n-1)
+	for _, row := range combine(n-1, k-1) {
+		row = append(row, n)
+		res = append(res, row)
+	}
+	res = append(res, combine(n-1, k)...)
+	return
+}
+
+func main() {
+	fmt.Println(combine(4, 2))
+	fmt.Println(combine(5, 4))
+	fmt.Println(combine(1, 1))
+}

+ 35 - 0
medium/78.go

@@ -0,0 +1,35 @@
+package main
+
+import (
+	"fmt"
+)
+
+func combine(nums []int, k int) (res [][]int) {
+	n := len(nums)
+	if n == k || k == 0 {
+		row := make([]int, k)
+		for i := range row {
+			row[i] = nums[i]
+		}
+		return append(res, row)
+	}
+	// C(k)(n) = C(k-1)(n-1) + C(k)(n-1)
+	for _, row := range combine(nums[:n-1], k-1) {
+		row = append(row, nums[n-1])
+		res = append(res, row)
+	}
+	res = append(res, combine(nums[:n-1], k)...)
+	return
+}
+
+func subsets(nums []int) (res [][]int) {
+	for i := 0; i <= len(nums); i++ {
+		res = append(res, combine(nums, i)...)
+	}
+	return
+}
+
+func main() {
+	a1 := []int{1, 2, 3}
+	fmt.Println(subsets(a1))
+}

+ 20 - 0
medium/79.go

@@ -0,0 +1,20 @@
+package main
+
+import "fmt"
+
+func exist(board [][]byte, word string) bool {
+
+	return false
+}
+
+func main() {
+	b1 := [][]byte{
+		{'A', 'B', 'C', 'E'},
+		{'S', 'F', 'C', 'S'},
+		{'A', 'D', 'E', 'E'},
+	}
+	fmt.Println(exist(b1, "ABCCED"))
+	fmt.Println(exist(b1, "SEE"))
+	fmt.Println(exist(b1, "ABCB"))
+	fmt.Println(exist(b1, "FSADEESCCBA"))
+}