邓心一 6 rokov pred
rodič
commit
5a86b39c53
66 zmenil súbory, kde vykonal 2090 pridanie a 5 odobranie
  1. 1 1
      easy/496.next-greater-element-i.go
  2. 46 0
      easy/501.find-mode-in-binary-search-tree.go
  3. 22 0
      easy/504.base-7.go
  4. 26 0
      easy/506.relative-ranks.go
  5. 17 0
      easy/507.perfect-number.go
  6. 13 0
      easy/509.fibonacci-number.go
  7. 15 0
      easy/520.detect-capital.go
  8. 16 0
      easy/521.longest-uncommon-subsequence-i.go
  9. 41 0
      easy/530.minimum-absolute-difference-in-bst.go
  10. 31 0
      easy/532.k-diff-pairs-in-an-array.go
  11. 25 0
      easy/538.convert-bst-to-greater-tree.go
  12. 19 0
      easy/541.reverse-string-ii.go
  13. 30 0
      easy/543.diameter-of-binary-tree.go
  14. 18 0
      easy/551.student-attendance-record-i.go
  15. 15 0
      easy/557.reverse-words-in-a-string-iii.go
  16. 27 0
      easy/561.array-partition-i.go
  17. 31 0
      easy/563.binary-tree-tilt.go
  18. 14 0
      easy/566.reshape-the-matrix.go
  19. 31 0
      easy/572.subtree-of-another-tree.go
  20. 13 0
      easy/575.distribute-candies.go
  21. 44 0
      easy/581.shortest-unsorted-continuous-subarray.go
  22. 20 0
      easy/594.longest-harmonious-subsequence.go
  23. 15 0
      easy/598.range-addition-ii.go
  24. 19 0
      easy/599.minimum-index-sum-of-two-lists.go
  25. 35 0
      hard/466.count-the-repetitions.go
  26. 59 0
      hard/480.sliding-window-median.go
  27. 85 0
      hard/488.zuma-game.go
  28. 83 0
      hard/493.reverse-pairs.go
  29. 39 0
      hard/514.freedom-trail.go
  30. 47 0
      hard/546.remove-boxes.go
  31. 29 0
      hard/552.student-attendance-record-ii.go
  32. 47 0
      hard/564.find-the-closest-palindrome.go
  33. 65 0
      hard/587.erect-the-fence.go
  34. 29 0
      medium/491.increasing-subsequences.java
  35. 31 4
      medium/497.random-point-in-non-overlapping-rectangles.go
  36. 25 0
      medium/498.diagonal-traverse.go
  37. 23 0
      medium/503.next-greater-element-ii.go
  38. 35 0
      medium/508.most-frequent-subtree-sum.go
  39. 34 0
      medium/513.find-bottom-left-tree-value.go
  40. 55 0
      medium/515.find-largest-value-in-each-tree-row.go
  41. 33 0
      medium/516.longest-palindromic-subsequence.go
  42. 35 0
      medium/518.coin-change-2.go
  43. 42 0
      medium/519.random-flip-matrix.go
  44. 35 0
      medium/522.longest-uncommon-subsequence-ii.go
  45. 21 0
      medium/523.continuous-subarray-sum.go
  46. 34 0
      medium/524.longest-word-in-dictionary-through-deleting.go
  47. 24 0
      medium/525.contiguous-array.go
  48. 18 0
      medium/526.beautiful-arrangement.go
  49. 37 0
      medium/528.random-pick-with-weight.go
  50. 92 0
      medium/529.minesweeper.go
  51. 36 0
      medium/535.encode-and-decode-tinyurl.java
  52. 9 0
      medium/537.complex-number-multiplication.go
  53. 28 0
      medium/539.minimum-time-difference.go
  54. 26 0
      medium/540.single-element-in-a-sorted-array.go
  55. 53 0
      medium/542.01-matrix.go
  56. 35 0
      medium/547.friend-circles.go
  57. 16 0
      medium/553.optimal-division.go
  58. 22 0
      medium/554.brick-wall.go
  59. 20 0
      medium/556.next-greater-element-iii.go
  60. 15 0
      medium/560.subarray-sum-equals-k.go
  61. 20 0
      medium/565.array-nesting.go
  62. 44 0
      medium/567.permutation-in-string.go
  63. 26 0
      medium/576.out-of-boundary-paths.go
  64. 27 0
      medium/583.delete-operation-for-two-strings.go
  65. 49 0
      medium/592.fraction-addition-and-subtraction.go
  66. 23 0
      medium/593.valid-square.go

+ 1 - 1
easy/496.next-greater-element-i.go

@@ -1,5 +1,5 @@
 func nextGreaterElement(findNums []int, nums []int) []int {
-	stack := make([]int, 0)
+	stack := make([]int, 0) // Keep a decease stack
 	next := make(map[int]int)
 	for _, i := range nums {
 		for l := len(stack); l != 0 && stack[l-1] < i; l = len(stack) {

+ 46 - 0
easy/501.find-mode-in-binary-search-tree.go

@@ -0,0 +1,46 @@
+var cnt int = 1
+var max int = 0
+var pre int = 0
+var ini bool = false
+
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func findMode(root *TreeNode) (res []int) {
+	cnt, max, pre = 1, 0, 0 // Remember to init global variables at the beginning!
+	ini = false
+	if root == nil {
+		return
+	}
+	inorder(root, &res)
+	return
+}
+
+func inorder(root *TreeNode, res *[]int) {
+	if root == nil {
+		return
+	} // Inorder traversal changes BST into increasing sequence.
+	inorder(root.Left, res)
+	if ini {
+		if root.Val == pre {
+			cnt++
+		} else {
+			cnt = 1
+		}
+	} else {
+		ini = true
+	}
+	if max < cnt {
+		*res = []int{root.Val}
+		max = cnt
+	} else if max == cnt {
+		*res = append(*res, root.Val)
+	}
+	pre = root.Val
+	inorder(root.Right, res)
+}

+ 22 - 0
easy/504.base-7.go

@@ -0,0 +1,22 @@
+func convertToBase7(num int) string {
+	if num == 0 {
+		return "0"
+	}
+	str := make([]rune, 0)
+	isNeg := false
+	if num < 0 {
+		isNeg = true
+		num = -num
+	}
+	for num != 0 {
+		str = append(str, rune(num%7+'0'))
+		num /= 7
+	}
+	for l, r := 0, len(str)-1; l < r; l, r = l+1, r-1 {
+		str[l], str[r] = str[r], str[l]
+	}
+	if isNeg {
+		return "-" + string(str)
+	}
+	return string(str)
+}

+ 26 - 0
easy/506.relative-ranks.go

@@ -0,0 +1,26 @@
+func findRelativeRanks(nums []int) []string {
+	idx2num := make(map[int]int)
+	for i := range nums {
+		idx2num[i] = nums[i]
+	}
+	sort.Sort(sort.Reverse(sort.IntSlice(nums)))
+	num2rank := make(map[int]int)
+	for i := range nums {
+		num2rank[nums[i]] = i
+	}
+	res := make([]string, len(nums))
+	for i := range res {
+		rank := num2rank[idx2num[i]]
+		switch rank {
+		case 0:
+			res[i] = "Gold Medal"
+		case 1:
+			res[i] = "Silver Medal"
+		case 2:
+			res[i] = "Bronze Medal"
+		default:
+			res[i] = strconv.Itoa(rank + 1)
+		}
+	}
+	return res
+}

+ 17 - 0
easy/507.perfect-number.go

@@ -0,0 +1,17 @@
+func checkPerfectNumber(num int) bool {
+	if num <= 1 {
+		return false
+	}
+	sum, sqrt := 1, int(math.Sqrt(float64(num)))
+	if sqrt*sqrt == num {
+		sum += sqrt
+		sqrt--
+	}
+	for i := 2; i <= sqrt; i++ {
+		if num%i == 0 {
+			sum += i
+			sum += num / i
+		}
+	}
+	return sum == num
+}

+ 13 - 0
easy/509.fibonacci-number.go

@@ -0,0 +1,13 @@
+func fib(N int) int {
+	// fib(0) = 0
+	if N <= 1 {
+		return N
+	}
+	a, b := 1, 0
+	for 1 < N {
+		a, b = a+b, a
+		N--
+	}
+	return a
+}
+

+ 15 - 0
easy/520.detect-capital.go

@@ -0,0 +1,15 @@
+func detectCapitalUse(word string) bool {
+	n := len(word)
+	if n <= 1 {
+		return true
+	}
+	up, lo := 0, 0
+	for _, r := range word {
+		if 'a' <= r && r <= 'z' {
+			lo++
+		} else if 'A' <= r && r <= 'Z' {
+			up++
+		}
+	}
+	return (up == 1 && 'A' <= word[0] && word[0] <= 'Z') || up == 0 || lo == 0
+}

+ 16 - 0
easy/521.longest-uncommon-subsequence-i.go

@@ -0,0 +1,16 @@
+func findLUSlength(a string, b string) (cnt int) {
+	m, n := len(a), len(b)
+	if m != n {
+		if m < n {
+			return n
+		}
+		return m
+	} else {
+		for i := range a {
+			if a[i] != b[i] {
+				return m
+			}
+		}
+		return -1
+	}
+}

+ 41 - 0
easy/530.minimum-absolute-difference-in-bst.go

@@ -0,0 +1,41 @@
+var pre int = 0
+var ini bool = false
+
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func getMinimumDifference(root *TreeNode) (diff int) {
+	pre, diff = 0, 1<<32-1
+	ini = false
+	inorder(root, &diff)
+	return
+}
+
+func inorder(root *TreeNode, diff *int) {
+	if root == nil {
+		return
+	}
+	inorder(root.Left, diff)
+	if ini {
+		d := abs(root.Val - pre)
+		if d < *diff {
+			*diff = d
+		}
+	} else {
+		ini = true
+	}
+	pre = root.Val
+	inorder(root.Right, diff)
+}
+
+func abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}

+ 31 - 0
easy/532.k-diff-pairs-in-an-array.go

@@ -0,0 +1,31 @@
+type pair struct {
+	_1 int
+	_2 int
+}
+
+func findPairs(nums []int, k int) (cnt int) {
+	n := len(nums)
+	if n < 2 {
+		return
+	}
+	sort.Ints(nums)
+	m := make(map[pair]bool)
+	fast, slow := 1, 0
+	for fast < n {
+		if det := nums[fast] - nums[slow]; det == k {
+			if _, ok := m[pair{nums[slow], nums[fast]}]; !ok {
+				cnt++
+				m[pair{nums[slow], nums[fast]}] = true
+			}
+			fast, slow = fast+1, slow+1
+		} else if det < k {
+			fast++
+		} else {
+			slow++
+			if fast == slow {
+				fast++
+			}
+		}
+	}
+	return
+}

+ 25 - 0
easy/538.convert-bst-to-greater-tree.go

@@ -0,0 +1,25 @@
+var sum int = 0
+
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func convertBST(root *TreeNode) *TreeNode {
+	sum = 0
+	inorder(root)
+	return root
+}
+
+func inorder(root *TreeNode) {
+	if root == nil {
+		return
+	}
+	inorder(root.Right)
+	root.Val += sum
+	sum = root.Val
+	inorder(root.Left)
+}

+ 19 - 0
easy/541.reverse-string-ii.go

@@ -0,0 +1,19 @@
+func reverseStr(s string, k int) string {
+	runes := []rune(s)
+	n := len(s)
+	beg, end := 0, k-1
+	for beg < n {
+		reverse(runes, n, beg, end)
+		beg, end = beg+2*k, end+2*k
+	}
+	return string(runes)
+}
+
+func reverse(runes []rune, n int, l int, r int) {
+	if n <= r {
+		r = n - 1
+	}
+	for ; l < r; l, r = l+1, r-1 {
+		runes[l], runes[r] = runes[r], runes[l]
+	}
+}

+ 30 - 0
easy/543.diameter-of-binary-tree.go

@@ -0,0 +1,30 @@
+var max int = 0
+
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func diameterOfBinaryTree(root *TreeNode) int {
+	max = 0
+	postorder(root, &max)
+	return
+}
+
+func postorder(root *TreeNode, max *int) int {
+	if root == nil {
+		return -1
+	}
+	l := postorder(root.Left, max) + 1
+	r := postorder(root.Right, max) + 1
+	if *max < l+r {
+		*max = l + r
+	}
+	if l < r {
+		return r
+	}
+	return l
+}

+ 18 - 0
easy/551.student-attendance-record-i.go

@@ -0,0 +1,18 @@
+func checkRecord(s string) bool {
+	a, l := 0, 0
+	for _, r := range s {
+		switch r {
+		case 'L':
+			l++
+		case 'A':
+			a++
+			fallthrough
+		default:
+			l = 0
+		}
+		if l == 3 || a == 2 {
+			return false
+		}
+	}
+	return true
+}

+ 15 - 0
easy/557.reverse-words-in-a-string-iii.go

@@ -0,0 +1,15 @@
+func reverseWords(s string) string {
+	beg, end, n := 0, 0, len(s)
+	res := make([]byte, n)
+	for end < n {
+		for beg = end; beg < n && s[beg] == ' '; beg++ {
+			res[beg] = ' '
+		}
+		for end = beg + 1; end < n && s[end] != ' '; end++ {
+		}
+		for l, r := beg, end-1; l <= r; l, r = l+1, r-1 {
+			res[l], res[r] = s[r], s[l]
+		}
+	}
+	return string(res)
+}

+ 27 - 0
easy/561.array-partition-i.go

@@ -0,0 +1,27 @@
+func arrayPairSum(nums []int) int {
+	set := [20001]int{}
+	for _, i := range nums {
+		set[i+10000]++
+	}
+	sum, flag := 0, 1
+	for i, val := range set {
+		if val != 0 {
+			if val&1 == 0 {
+				sum += val / 2 * (i - 10000)
+			} else {
+				sum += (val + flag) / 2 * (i - 10000)
+				flag ^= 1
+			}
+		}
+	}
+	return sum
+}
+
+func arrayPairSumSort(nums []int) int {
+	sort.Ints(nums)
+	sum := 0
+	for i := len(nums) - 2; 0 <= i; i -= 2 {
+		sum += nums[i]
+	}
+	return sum
+}

+ 31 - 0
easy/563.binary-tree-tilt.go

@@ -0,0 +1,31 @@
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func findTilt(root *TreeNode) int {
+	tilt := 0
+	postorder(root, &tilt)
+	return tilt
+}
+
+func postorder(root *TreeNode, tilt *int) int {
+	if root == nil {
+		return 0
+	}
+	l := postorder(root.Left, tilt)
+	r := postorder(root.Right, tilt)
+	sum := l + r + root.Val
+	*tilt += abs(l - r)
+	return sum
+}
+
+func abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}

+ 14 - 0
easy/566.reshape-the-matrix.go

@@ -0,0 +1,14 @@
+func matrixReshape(nums [][]int, r int, c int) [][]int {
+	m, n := len(nums), len(nums[0])
+	if m*n != r*c || (m == r && n == c) {
+		return nums
+	}
+	res := make([][]int, r)
+	for i := range res {
+		res[i] = make([]int, c)
+	}
+	for i := 0; i < r*c; i++ {
+		res[i/c][i%c] = nums[i/n][i%n]
+	}
+	return res
+}

+ 31 - 0
easy/572.subtree-of-another-tree.go

@@ -0,0 +1,31 @@
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func isSubtree(s *TreeNode, t *TreeNode) bool {
+	return postorder(s, t)
+}
+
+func postorder(s *TreeNode, t *TreeNode) bool {
+	if s == nil {
+		return s == t
+	}
+	if postorder(s.Left, t) || postorder(s.Right, t) {
+		return true
+	}
+	return isSametree(s, t)
+}
+
+func isSametree(s *TreeNode, t *TreeNode) bool {
+	if s == nil || t == nil {
+		return s == t
+	}
+	if s.Val != t.Val {
+		return false
+	}
+	return isSametree(s.Left, t.Left) && isSametree(s.Right, t.Right)
+}

+ 13 - 0
easy/575.distribute-candies.go

@@ -0,0 +1,13 @@
+type none struct{}
+
+func distributeCandies(candies []int) int {
+	set := make(map[int]none)
+	for _, c := range candies {
+		set[c] = none{}
+	}
+	if half, kind := len(candies)/2, len(set); kind <= half {
+		return kind
+	} else {
+		return half
+	}
+}

+ 44 - 0
easy/581.shortest-unsorted-continuous-subarray.go

@@ -0,0 +1,44 @@
+func findUnsortedSubarray(nums []int) int {
+	i, j, max, min := 0, -1, nums[0], nums[len(nums)-1]
+	for l, r := 0, len(nums)-1; 0 <= r; l, r = l+1, r-1 {
+		max = maxInt(max, nums[l])
+		min = minInt(min, nums[r])
+		if nums[l] != max {
+			j = l // The last num that < max
+		}
+		if nums[r] != min {
+			i = r // The last num that > min
+		}
+	}
+	return j - i + 1
+}
+
+func maxInt(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}
+
+func minInt(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+func findUnsortedSubarraySort(nums []int) int {
+	n := len(nums)
+	sorted := make([]int, n)
+	copy(sorted, nums)
+	sort.Ints(sorted)
+	l, r := 0, n-1
+	for ; l < n && nums[l] == sorted[l]; l++ {
+	}
+	if l == n {
+		return 0
+	}
+	for ; nums[r] == sorted[r]; r-- {
+	}
+	return r - l + 1
+}

+ 20 - 0
easy/594.longest-harmonious-subsequence.go

@@ -0,0 +1,20 @@
+func findLHS(nums []int) int {
+	freq := make(map[int]int)
+	for _, i := range nums {
+		freq[i]++
+	}
+	l := 0
+	for k, v := range freq {
+		if val, ok := freq[k+1]; ok {
+			l = maxInt(l, val+v)
+		}
+	}
+	return l
+}
+
+func maxInt(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}

+ 15 - 0
easy/598.range-addition-ii.go

@@ -0,0 +1,15 @@
+func maxCount(m int, n int, ops [][]int) int {
+	y, x := m, n
+	for _, op := range ops {
+		y = minInt(y, op[0])
+		x = minInt(x, op[1])
+	}
+	return y * x
+}
+
+func minInt(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}

+ 19 - 0
easy/599.minimum-index-sum-of-two-lists.go

@@ -0,0 +1,19 @@
+func findRestaurant(list1 []string, list2 []string) []string {
+	res := make([]string, 0)
+	min := len(list1) + len(list2)
+	m := make(map[string]int)
+	for i, s := range list1 {
+		m[s] = i
+	}
+	for i, s := range list2 {
+		if val, ok := m[s]; ok {
+			if sum := val + i; sum < min {
+				min = sum
+				res = []string{s}
+			} else if sum == min {
+				res = append(res, s)
+			}
+		}
+	}
+	return res
+}

+ 35 - 0
hard/466.count-the-repetitions.go

@@ -0,0 +1,35 @@
+func getMaxRepetitions(s1 string, n1 int, s2 string, n2 int) int {
+	// dp[i][k] = dp[i][k-1] + dp[(i+dp[i][k-1])%m][k-1], m = len(s1)
+	// dp[i][k] means the length required to match 2^k of s2
+	// from the ith char of s1.
+	m, n := len(s1), len(s2)
+	r1, r2 := []rune(s1), []rune(s2)
+	dp := make([][]int, m+1)
+	for i := range dp {
+		dp[i] = make([]int, 31) // 2^30 is the limit, cauz MaxInt32 < 2^31
+	}
+	for i := 0; i < m; i++ {
+		l1, l2 := i, 0
+		for l2 < n { // Match 2^0 of s2
+			for l1 < n1*m && r1[l1%m] != r2[l2] {
+				l1++
+			}
+			l1, l2 = l1+1, l2+1
+		}
+		dp[i][0] = l1 - i
+	}
+	for k := 1; k < 31; k++ {
+		for i := 0; i < m; i++ {
+			dp[i][k] = dp[i][k-1] + dp[(i+dp[i][k-1])%m][k-1]
+		}
+	}
+	ans := int64(0)
+	beg := 0
+	for k := 30; 0 <= k; k-- {
+		for beg+dp[beg%m][k] <= n1*m {
+			ans += 1 << uint(k)
+			beg += dp[beg%m][k]
+		}
+	}
+	return int(ans) / n2
+}

+ 59 - 0
hard/480.sliding-window-median.go

@@ -0,0 +1,59 @@
+type ints []int
+
+func (is ints) search(x int) int {
+	beg, end := 0, len(is)-1
+	for beg <= end {
+		mid := beg + (end-beg)/2
+		if is[mid] < x {
+			beg = mid + 1
+		} else {
+			end = mid - 1
+		}
+	}
+	return beg
+}
+
+func (is *ints) insert(x int) {
+	idx := is.search(x)
+	if n := len(*is); idx == n {
+		*is = append(*is, x)
+	} else {
+		nis := make([]int, n+1)
+		copy(nis, (*is)[:idx])
+		nis[idx] = x
+		copy(nis[idx+1:], (*is)[idx:])
+		*is = nis
+	}
+}
+
+func (is *ints) delete(x int) {
+	idx := is.search(x)
+	if n := len(*is); idx == n-1 {
+		*is = (*is)[:n-1]
+	} else {
+		copy((*is)[idx:], (*is)[idx+1:])
+		*is = (*is)[:n-1]
+	}
+}
+
+func medianSlidingWindow(nums []int, k int) (ans []float64) {
+	n := len(nums)
+	if n < k || k == 0 {
+		return
+	}
+	var win ints = make([]int, 0)
+	for i := 0; i < n; i++ {
+		if k <= i {
+			win.delete(nums[i-k])
+		}
+		win.insert(nums[i])
+		if k-1 <= i {
+			if k%2 == 1 {
+				ans = append(ans, float64(win[k/2]))
+			} else {
+				ans = append(ans, float64(win[k/2-1]+win[k/2])/2.0)
+			}
+		}
+	}
+	return
+}

+ 85 - 0
hard/488.zuma-game.go

@@ -0,0 +1,85 @@
+type pair struct { // The presentation of the board is the key!
+	_1 rune
+	_2 int
+}
+
+const INF int = 1e9
+
+func findMinStep(board string, hand string) int {
+	li := list.New()
+	n := len(board)
+	runes := []rune(board)
+	prev := pair{runes[0], 1}
+	for i := 1; i < n; i++ {
+		if runes[i] == prev._1 {
+			prev._2++
+		} else {
+			li.PushBack(prev)
+			prev = pair{runes[i], 1}
+		}
+	}
+	li.PushBack(prev)
+	m := make(map[rune]int)
+	for _, r := range hand {
+		m[r]++
+	}
+	// R, Y, B, G, W
+	if min := dfs(li, &m); min == INF {
+		return -1
+	} else {
+		return min
+	}
+}
+
+func dfs(li *list.List, m *map[rune]int) int {
+	clearBoard(li)
+	if li.Len() == 0 {
+		return 0
+	} else if len(*m) == 0 {
+		return INF
+	}
+	min := INF
+	for it := li.Front(); it != nil; it = it.Next() {
+		p := it.Value.(pair)
+		if cnt, ok := (*m)[p._1]; ok && 3 <= cnt+p._2 {
+			need := 3 - p._2
+			p._2 = 3
+			it.Value = p
+			(*m)[p._1] = cnt - need
+			if cnt == need {
+				delete(*m, p._1)
+			}
+			nli := list.New()
+			nli.PushBackList(li)
+			ret := dfs(nli, m) + need
+			if ret < min {
+				min = ret
+			}
+			p._2 -= need
+			it.Value = p
+			(*m)[p._1] = cnt
+		}
+	}
+	return min
+}
+
+func clearBoard(li *list.List) {
+	it := li.Front()
+	for it != nil {
+		if nxt := it.Next(); nxt != nil && nxt.Value.(pair)._1 == it.Value.(pair)._1 {
+			p := pair{it.Value.(pair)._1, it.Value.(pair)._2 + nxt.Value.(pair)._2}
+			it.Value = p
+			li.Remove(nxt)
+		} else if 3 <= it.Value.(pair)._2 {
+			pre := it.Prev()
+			li.Remove(it)
+			if pre != nil {
+				it = pre
+			} else {
+				it = nxt
+			}
+		} else {
+			it = nxt
+		}
+	}
+}

+ 83 - 0
hard/493.reverse-pairs.go

@@ -0,0 +1,83 @@
+func reversePairs(nums []int) int {
+	return mergeSort(nums, 0, len(nums)-1)
+}
+
+func mergeSort(nums []int, beg int, end int) int {
+	if end <= beg {
+		return 0
+	}
+	l, m := beg, beg+(end-beg)/2
+	r, p, k := m+1, m+1, 0
+	res := mergeSort(nums, beg, m) + mergeSort(nums, r, end)
+	merge := make([]int, end-beg+1)
+	for l <= m {
+		for ; p <= end && 2*nums[p] < nums[l]; p++ {
+		} // Advance l once each loop to calculate the cnt of reverse pairs
+		res += p - m - 1
+		for r <= end && nums[r] <= nums[l] {
+			merge[k] = nums[r]
+			k, r = k+1, r+1
+		}
+		merge[k] = nums[l]
+		k, l = k+1, l+1
+	}
+	for r <= end {
+		merge[k] = nums[r]
+		k, r = k+1, r+1
+	}
+	copy(nums[beg:end+1], merge)
+	return res
+}
+
+// ---------------------dividing line for TLE binary search algorithm---------------------
+
+type ints [][]int
+
+func (is ints) search(x int, beg int, end int) int {
+	for beg <= end {
+		mid := beg + (end-beg)/2
+		if is[mid][0] < x {
+			beg = mid + 1
+		} else {
+			end = mid - 1
+		}
+	}
+	return beg
+}
+
+func (is *ints) insert(x int) int {
+	beg, end := 0, len(*is)
+	beg = is.search(2*x+1, beg, end-1)
+	cnt := 0
+	for i := beg; i < end; i++ {
+		cnt += (*is)[i][1]
+	}
+	if beg == end {
+		beg--
+	}
+	if x < 0 {
+		beg = is.search(x, 0, end-1)
+	} else {
+		beg = is.search(x, 0, beg)
+	}
+	if beg == end {
+		*is = append(*is, []int{x, 1})
+	} else if (*is)[beg][0] == x {
+		(*is)[beg][1]++
+	} else {
+		nis := make([][]int, end+1)
+		copy(nis, (*is)[:beg])
+		nis[beg] = []int{x, 1}
+		copy(nis[beg+1:], (*is)[beg:])
+		*is = nis
+	}
+	return cnt
+}
+
+func reversePairsTLE(nums []int) (cnt int) {
+	var is ints = make([][]int, 0)
+	for _, i := range nums {
+		cnt += is.insert(i)
+	}
+	return
+}

+ 39 - 0
hard/514.freedom-trail.go

@@ -0,0 +1,39 @@
+func findRotateSteps(ring string, key string) int {
+	// dp[i][j] means the min steps required to get the key[j] from ring[i],
+	// then dp[0][0] is the answer.
+	m, n := len(ring), len(key)
+	if n == 0 {
+		return 0
+	}
+	const INF int = 1e9
+	dp := make([][]int, m)
+	for i := range dp {
+		dp[i] = make([]int, n+1)
+	} // dp[i][j] = min(dp[i][j], dist(i, k) + dp[k][j+1])
+	for j := n - 1; 0 <= j; j-- {
+		for i := 0; i < m; i++ {
+			dp[i][j] = INF
+			for k := 0; k < m; k++ {
+				if ring[k] == key[j] {
+					step := minInt(abs(k-i), m-abs(k-i))
+					dp[i][j] = minInt(dp[i][j], step+dp[k][j+1])
+				}
+			}
+		}
+	}
+	return dp[0][0] + n
+}
+
+func abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}
+
+func minInt(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}

+ 47 - 0
hard/546.remove-boxes.go

@@ -0,0 +1,47 @@
+const MAX_N int = 100
+
+var dp map[int]int
+var length []int
+
+func removeBoxes(boxes []int) int {
+	n := len(boxes)
+	dp = make(map[int]int)
+	length = make([]int, n)
+	for i := 1; i < n; i++ {
+		if boxes[i] == boxes[i-1] {
+			length[i] = length[i-1] + 1
+		}
+	}
+	return dfs(boxes, 0, len(boxes)-1, 0)
+}
+
+func dfs(boxes []int, l, r, k int) int {
+	// dp[l][r][k] = dp[l][r-1][0] + (k+1)^2, drop box[r]
+	//             = dp[l][p][k+1] + dp[p+1][r-1][0],
+	// box[p] == box[j], remove boxes at [p+1, r-1] and attach
+	// box[j] to box[p]
+	if r < l {
+		return 0
+	}
+	k += length[r]
+	r -= length[r]
+	key := ((l*MAX_N)+r)*MAX_N + k
+	if val, ok := dp[key]; ok {
+		return val
+	}
+	res := dfs(boxes, l, r-1, 0) + (k+1)*(k+1)
+	for i := l; i < r; i++ {
+		if boxes[i] == boxes[r] {
+			res = maxInt(res, dfs(boxes, l, i, k+1)+dfs(boxes, i+1, r-1, 0))
+		}
+	}
+	dp[key] = res
+	return res
+}
+
+func maxInt(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}

+ 29 - 0
hard/552.student-attendance-record-ii.go

@@ -0,0 +1,29 @@
+const MOD int = 1000000007
+
+func checkRecord(n int) int {
+	// A, L, P
+	var dp = [2][3]int{{1, 1, 0}, {1, 0, 0}}
+	for i := 1; i < n; i++ {
+		var nxt [2][3]int
+		for A := 0; A <= 1; A++ {
+			for L := 0; L <= 2; L++ {
+				nxt[A][0] += dp[A][L] // Append P
+				if L > 0 {
+					nxt[A][L] += dp[A][L-1] // Append L
+				}
+				if A > 0 {
+					nxt[A][0] += dp[A-1][L] // Append A
+				}
+				nxt[A][L] %= MOD
+			}
+		}
+		dp = nxt
+	}
+	sum := 0
+	for i := range dp {
+		for _, v := range dp[i] {
+			sum = (sum + v) % MOD
+		}
+	}
+	return sum
+}

+ 47 - 0
hard/564.find-the-closest-palindrome.go

@@ -0,0 +1,47 @@
+func nearestPalindromic(n string) string {
+	set := make([]int, 0, 5)
+	l := len(n)
+	set = append(set, int(math.Pow10(l))+1)
+	set = append(set, int(math.Pow10(l-1))-1)
+	r1, r2, r3 := []rune(n), []rune(n), []rune(n)
+	beg, end := l/2-1+l&1, l/2
+	if r1[beg] != '0' {
+		r1[beg]--
+	}
+	if r3[beg] != '9' {
+		r3[beg]++
+	}
+	for ; end < l; beg, end = beg-1, end+1 {
+		r1[end] = r1[beg]
+		r2[end] = r2[beg]
+		r3[end] = r3[beg]
+	}
+	n1, _ := strconv.Atoi(string(r1))
+	n2, _ := strconv.Atoi(string(r2))
+	n3, _ := strconv.Atoi(string(r3))
+	set = append(set, n1)
+	set = append(set, n2)
+	set = append(set, n3)
+	num, _ := strconv.Atoi(n)
+	min, res := math.MaxInt32, math.MaxInt32
+	for _, i := range set {
+		if det := abs(num - i); det != 0 && det < min || (det == min && i < res) {
+			min, res = det, i
+		}
+	}
+	return strconv.Itoa(res)
+}
+
+func minInt(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+func abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}

+ 65 - 0
hard/587.erect-the-fence.go

@@ -0,0 +1,65 @@
+type Points []Point
+
+func (pts Points) Len() int { return len(pts) }
+func (pts Points) Less(i, j int) bool {
+	if pts[i].X != pts[j].X {
+		return pts[i].X < pts[j].X
+	}
+	return pts[i].Y < pts[j].Y
+}
+func (pts Points) Swap(i, j int) { pts[i], pts[j] = pts[j], pts[i] }
+
+/**
+ * Definition for a point.
+ * type Point struct {
+ *     X int
+ *     Y int
+ * }
+ */
+func outerTrees(points []Point) []Point {
+	k, n := 0, len(points)
+	if n == 1 {
+		return points
+	}
+	sort.Sort(Points(points))
+	pts := make([]Point, n)
+	for i := 0; i < n; i++ {
+		for 1 < k { // a x b = dx1*dy2 - dx2*dy1 <= 0
+			dx1, dx2 := pts[k-1].X-pts[k-2].X, points[i].X-pts[k-1].X
+			dy1, dy2 := pts[k-1].Y-pts[k-2].Y, points[i].Y-pts[k-1].Y
+			if dx1*dy2 <= dx2*dy1 {
+				break
+			}
+			k--
+		}
+		pts[k] = points[i]
+		k++
+	}
+	set := make(map[Point]bool)
+	for i := 0; i < k; i++ {
+		set[pts[i]] = true
+	}
+	k = 0
+	for i := n - 1; 0 <= i; i-- {
+		for 1 < k { // a x b = dx1*dy2 - dx2*dy1 <= 0
+			dx1, dx2 := pts[k-1].X-pts[k-2].X, points[i].X-pts[k-1].X
+			dy1, dy2 := pts[k-1].Y-pts[k-2].Y, points[i].Y-pts[k-1].Y
+			if dx1*dy2 <= dx2*dy1 {
+				break
+			}
+			k--
+		}
+		pts[k] = points[i]
+		k++
+	}
+	for i := 0; i < k; i++ {
+		set[pts[i]] = true
+	}
+	res := make([]Point, len(set))
+	k = 0
+	for p, _ := range set {
+		res[k] = p
+		k++
+	}
+	return res
+}

+ 29 - 0
medium/491.increasing-subsequences.java

@@ -0,0 +1,29 @@
+import java.util.LinkedList;
+
+class Solution {
+    public List<List<Integer>> findSubsequences(int[] nums) {
+        Set<LinkedList<Integer>> set = new HashSet<>();
+        List<LinkedList<Integer>> lists = new LinkedList<>();
+        for (int i : nums) {
+            lists.clear();
+            for (LinkedList<Integer> list : set) {
+                if (list.getLast() <= i) {
+                    LinkedList<Integer> newList = new LinkedList<>(list);
+                    newList.add(i);
+                    lists.add(newList);
+                }
+            }
+            for (LinkedList<Integer> list : lists) {
+                set.add(list);
+            }
+            LinkedList<Integer> list = new LinkedList<>();
+            list.add(i);
+            set.add(list);
+        }
+        List<List<Integer>> res = new LinkedList<>();
+        for (List list : set) {
+            if (1 < list.size()) res.add(list);
+        }
+        return res;
+    }
+}

+ 31 - 4
medium/497.random-point-in-non-overlapping-rectangles.go

@@ -1,13 +1,40 @@
 type Solution struct {
-	
+	size  int
+	rects [][]int
+	areas []int
 }
 
-func Constructor(rects [][]int) Solution {
-
+func Constructor(rects [][]int) (sol Solution) {
+	sol.size = len(rects)
+	sol.areas = make([]int, sol.size+1)
+	sol.rects = rects
+	for i := 0; i < sol.size; i++ {
+		r := rects[i]
+		w, h := r[2]-r[0]+1, r[3]-r[1]+1
+		sol.areas[i+1] = sol.areas[i] + w*h
+	}
+	return
 }
 
 func (this *Solution) Pick() []int {
-
+	idx := rand.Intn(this.areas[this.size])
+	beg, end := 1, this.size
+	for beg <= end {
+		mid := beg + (end-beg)/2
+		if this.areas[mid] < idx {
+			beg = mid + 1
+		} else {
+			end = mid - 1
+		}
+	}
+	if this.areas[beg] != idx {
+		beg--
+	}
+	pos := idx - this.areas[beg]
+	r := this.rects[beg]
+	w := r[2] - r[0] + 1
+	dx, dy := pos%w, pos/w
+	return []int{r[0] + dx, r[1] + dy}
 }
 
 /**

+ 25 - 0
medium/498.diagonal-traverse.go

@@ -0,0 +1,25 @@
+func findDiagonalOrder(matrix [][]int) (ans []int) {
+	m := len(matrix)
+	if m == 0 {
+		return
+	}
+	n := len(matrix[0])
+	if n == 0 {
+		return
+	}
+	x, y := 0, 0
+	dx, dy := 1, -1
+	for i := 0; i < m*n; i++ {
+		ans = append(ans, matrix[y][x])
+		if ny := y + dy; (ny == -1 || ny == m) && x != n-1 {
+			dx, dy = -dx, -dy
+			x++
+		} else if nx := x + dx; nx == -1 || nx == n {
+			dx, dy = -dx, -dy
+			y++
+		} else {
+			x, y = nx, ny
+		}
+	}
+	return
+}

+ 23 - 0
medium/503.next-greater-element-ii.go

@@ -0,0 +1,23 @@
+func nextGreaterElements(nums []int) []int {
+	n := len(nums)
+	next := make([]int, n)
+	if n == 0 {
+		return next
+	}
+	next[0] = -1
+	for i := 1; i < n; i *= 2 {
+		copy(next[i:], next[:i])
+	}
+	st := make([]int, 0)
+	l := 0
+	for i := 0; i < 2*n; i++ { // Keep a decreasing stack, and traversal for twice
+		for l != 0 && nums[st[l-1]] < nums[i%n] {
+			next[st[l-1]] = nums[i%n]
+			st = st[:l-1]
+			l--
+		}
+		st = append(st, i%n)
+		l++
+	}
+	return next
+}

+ 35 - 0
medium/508.most-frequent-subtree-sum.go

@@ -0,0 +1,35 @@
+var max int = 0
+
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func findFrequentTreeSum(root *TreeNode) (res []int) {
+	max = 0
+	freq := make(map[int]int)
+	postorder(root, &freq)
+	for k, v := range freq {
+		if v == max {
+			res = append(res, k)
+		}
+	}
+	return
+}
+
+func postorder(root *TreeNode, freq *map[int]int) int {
+	if root == nil {
+		return 0
+	}
+	l := postorder(root.Left, freq)
+	r := postorder(root.Right, freq)
+	sum := l + r + root.Val
+	(*freq)[sum]++
+	if max < (*freq)[sum] {
+		max = (*freq)[sum]
+	}
+	return sum
+}

+ 34 - 0
medium/513.find-bottom-left-tree-value.go

@@ -0,0 +1,34 @@
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func findBottomLeftValue(root *TreeNode) int {
+	if root == nil {
+		return -1
+	}
+	queue := make([]*TreeNode, 0)
+	queue = append(queue, root)
+	for len(queue) != 0 {
+		bl := queue[0].Val
+		nextLV := make([]*TreeNode, 0)
+		for len(queue) != 0 {
+			head := queue[0]
+			queue = queue[1:]
+			if head.Left != nil {
+				nextLV = append(nextLV, head.Left)
+			}
+			if head.Right != nil {
+				nextLV = append(nextLV, head.Right)
+			}
+		}
+		if len(nextLV) == 0 {
+			return bl
+		}
+		queue = nextLV
+	}
+	return -1
+}

+ 55 - 0
medium/515.find-largest-value-in-each-tree-row.go

@@ -0,0 +1,55 @@
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ *     Val int
+ *     Left *TreeNode
+ *     Right *TreeNode
+ * }
+ */
+func largestValues(root *TreeNode) (res []int) {
+	preorder(root, 0, &res) // DFS
+	return
+}
+
+func preorder(root *TreeNode, depth int, res *[]int) {
+	if root == nil {
+		return
+	}
+	if depth == len(*res) {
+		*res = append(*res, root.Val)
+	} else if (*res)[depth] < root.Val {
+		(*res)[depth] = root.Val
+	}
+	preorder(root.Left, depth+1, res)
+	preorder(root.Right, depth+1, res)
+}
+
+func largestValuesBFS(root *TreeNode) (res []int) {
+	if root == nil {
+		return
+	}
+	queue := make([]*TreeNode, 0)
+	queue = append(queue, root)
+	size := 1
+	for size != 0 {
+		max, l := queue[0].Val, size
+		for i := 0; i < l; i++ {
+			node := queue[0]
+			queue = queue[1:]
+			size--
+			if max < node.Val {
+				max = node.Val
+			}
+			if node.Left != nil {
+				queue = append(queue, node.Left)
+				size++
+			}
+			if node.Right != nil {
+				queue = append(queue, node.Right)
+				size++
+			}
+		}
+		res = append(res, max)
+	}
+	return
+}

+ 33 - 0
medium/516.longest-palindromic-subsequence.go

@@ -0,0 +1,33 @@
+func longestPalindromeSubseq(s string) int {
+	n := len(s)
+	if n < 2 {
+		return n
+	}
+	runes := []rune(s)
+	dp := make([][]int, n)
+	for i := range dp {
+		dp[i] = make([]int, n)
+		dp[i][i] = 1
+	}
+	// dp[i][j], len of LPS of s[i:j+1]
+	// dp[i][j] = max(dp[i][j], dp[i+1][j-1]+2), if s[i] == s[j]
+	// dp[i][j] = max(dp[i+1][j], dp[i][j-1]), if s[i] != s[j]
+	for l := 1; l < n; l++ {
+		for i := 0; i+l < n; i++ {
+			if runes[i] == runes[i+l] {
+				dp[i][i+l] = maxInt(dp[i][i+l], dp[i+1][i+l-1]+2)
+				// If j-1 < i+1, dp[i][j] = 0
+			} else {
+				dp[i][i+l] = maxInt(dp[i+1][i+l], dp[i][i+l-1])
+			}
+		}
+	}
+	return dp[0][n-1]
+}
+
+func maxInt(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}

+ 35 - 0
medium/518.coin-change-2.go

@@ -0,0 +1,35 @@
+func change(amount int, coins []int) int {
+	dp := make([]int, amount+1)
+	dp[0] = 1
+	for _, c := range coins { // dp[i+c] += dp[i]
+		for i := 0; i <= amount-c; i++ {
+			dp[i+c] += dp[i]
+		}
+	}
+	return dp[amount]
+}
+
+type pair struct {
+	_1 int
+	_2 int
+}
+
+func changeDFS(amount int, coins []int) int { // Memory search
+	m := make(map[pair]int)
+	return dfs(amount, coins, 0, m)
+}
+
+func dfs(amount int, coins []int, i int, m map[pair]int) (sum int) {
+	if amount == 0 {
+		return 1
+	} else if len(coins) == i {
+		return 0
+	} else if val, ok := m[pair{amount, i}]; ok {
+		return val
+	}
+	for c := 0; c <= amount; c += coins[i] {
+		sum += dfs(amount-c, coins, i+1, m)
+	}
+	m[pair{amount, i}] = sum
+	return
+}

+ 42 - 0
medium/519.random-flip-matrix.go

@@ -0,0 +1,42 @@
+type Solution struct {
+	m    map[int]int
+	size int
+	rows int
+	cols int
+}
+
+func Constructor(n_rows int, n_cols int) Solution {
+	return Solution{
+		m:    make(map[int]int),
+		size: n_rows * n_cols,
+		rows: n_rows,
+		cols: n_cols,
+	}
+}
+
+func (this *Solution) Flip() []int {
+	idx := rand.Intn(this.size)
+	i := idx
+	this.size--
+	if val, ok := this.m[idx]; ok {
+		idx = val
+	} // The trick is very important!
+	if val, ok := this.m[this.size]; ok {
+		this.m[i] = val
+	} else {
+		this.m[i] = this.size
+	}
+	return []int{idx / this.cols, idx % this.cols}
+}
+
+func (this *Solution) Reset() {
+	this.m = make(map[int]int)
+	this.size = this.rows * this.cols
+}
+
+/**
+ * Your Solution object will be instantiated and called as such:
+ * obj := Constructor(n_rows, n_cols);
+ * param_1 := obj.Flip();
+ * obj.Reset();
+ */

+ 35 - 0
medium/522.longest-uncommon-subsequence-ii.go

@@ -0,0 +1,35 @@
+type strslice []string
+
+func (ss strslice) Len() int           { return len(ss) }
+func (ss strslice) Less(i, j int) bool { return len(ss[j]) < len(ss[i]) }
+func (ss strslice) Swap(i, j int)      { ss[i], ss[j] = ss[j], ss[i] }
+
+func findLUSlength(strs []string) int {
+	sort.Sort(strslice(strs))
+	m := make(map[string]int)
+	for i := range strs {
+		m[strs[i]]++
+	}
+	for i := range strs {
+		if val, _ := m[strs[i]]; val == 1 {
+			j := 0
+			for ; j < i && !isSubstr(strs[j], strs[i]); j++ {
+			}
+			if j == i {
+				return len(strs[i])
+			}
+		}
+	}
+	return -1
+}
+
+func isSubstr(s, t string) bool {
+	i, j, m, n := 0, 0, len(s), len(t)
+	s1, s2 := []rune(s), []rune(t)
+	for ; i < m && j < n; j++ {
+		for ; i < m && s1[i] != s2[j]; i++ {
+		}
+		i++
+	}
+	return i <= m && j == n
+}

+ 21 - 0
medium/523.continuous-subarray-sum.go

@@ -0,0 +1,21 @@
+func checkSubarraySum(nums []int, k int) bool {
+	n := len(nums)
+	if n < 2 {
+		return false
+	}
+	dp := make([]int, n)
+	copy(dp, nums)
+	for l := n - 1; 1 <= l; l-- {
+		for i := 0; i < l; i++ {
+			dp[i] += nums[i+n-l]
+			if k == 0 {
+				if dp[i] == k {
+					return true
+				}
+			} else if dp[i]%k == 0 {
+				return true
+			}
+		}
+	}
+	return false
+}

+ 34 - 0
medium/524.longest-word-in-dictionary-through-deleting.go

@@ -0,0 +1,34 @@
+type strslice []string
+
+func (ss strslice) Len() int { return len(ss) }
+func (ss strslice) Less(i, j int) bool {
+	if m, n := len(ss[i]), len(ss[j]); m != n {
+		return n < m
+	}
+	return ss[i] < ss[j]
+}
+func (ss strslice) Swap(i, j int) { ss[i], ss[j] = ss[j], ss[i] }
+
+func findLongestWord(s string, d []string) string {
+	sort.Sort(strslice(d))
+	for i := range d {
+		if isSubstr(s, d[i]) {
+			return d[i]
+		}
+	}
+	return ""
+}
+
+func isSubstr(s, t string) bool {
+	i, j, m, n := 0, 0, len(s), len(t)
+	if m < n {
+		return false
+	}
+	s1, s2 := []rune(s), []rune(t)
+	for ; i < m && j < n; j++ {
+		for ; i < m && s1[i] != s2[j]; i++ {
+		}
+		i++
+	}
+	return i <= m && j == n
+}

+ 24 - 0
medium/525.contiguous-array.go

@@ -0,0 +1,24 @@
+func findMaxLength(nums []int) (max int) {
+	n := len(nums)
+	if n < 2 {
+		return
+	}
+	sum := make([]int, n+1)
+	m := make(map[int]int)
+	m[0] = 0
+	for i := range nums { // Range sum + two sum
+		if nums[i] == 0 {
+			sum[i+1] = sum[i] - 1
+		} else {
+			sum[i+1] = sum[i] + 1
+		}
+		if val, ok := m[sum[i+1]]; ok {
+			if max < i+1-val {
+				max = i + 1 - val
+			}
+		} else {
+			m[sum[i+1]] = i + 1
+		}
+	}
+	return
+}

+ 18 - 0
medium/526.beautiful-arrangement.go

@@ -0,0 +1,18 @@
+func countArrangement(N int) (cnt int) {
+	dfs(N, 1, 0, &cnt)
+	return cnt
+}
+
+func dfs(N int, i int, used int, cnt *int) {
+	if N < i {
+		(*cnt)++
+		return
+	}
+	for a := 1; a <= N; a++ {
+		if mask := 1 << uint(a); used&mask == 0 && (a%i == 0 || i%a == 0) {
+			used |= mask
+			dfs(N, i+1, used, cnt)
+			used ^= mask // Backtracking
+		}
+	}
+}

+ 37 - 0
medium/528.random-pick-with-weight.go

@@ -0,0 +1,37 @@
+type Solution struct {
+	sum []int
+	l   int
+	n   int
+}
+
+func Constructor(w []int) (sol Solution) {
+	n := len(w)
+	sol.sum = make([]int, n+1)
+	for i := range w {
+		sol.sum[i+1] = sol.sum[i] + w[i]
+	}
+	sol.n, sol.l = sol.sum[n], n+1
+	return
+}
+
+func (this *Solution) PickIndex() int {
+	idx := rand.Intn(this.n) + 1
+	beg, end := 1, this.l-1
+	for beg <= end {
+		mid := beg + (end - beg)
+		if val := this.sum[mid]; val == idx {
+			return mid - 1
+		} else if val < idx {
+			beg = mid + 1
+		} else {
+			end = mid - 1
+		}
+	}
+	return beg - 1
+}
+
+/**
+ * Your Solution object will be instantiated and called as such:
+ * obj := Constructor(w);
+ * param_1 := obj.PickIndex();
+ */

+ 92 - 0
medium/529.minesweeper.go

@@ -0,0 +1,92 @@
+func updateBoard(board [][]byte, click []int) [][]byte {
+	y, x := click[0], click[1]
+	if board[y][x] != 'E' {
+		if board[y][x] == 'M' {
+			board[y][x] = 'X'
+		}
+		return board
+	}
+	m, n := len(board), len(board[0])
+	count := make([][]int, m)
+	for i := range count {
+		count[i] = make([]int, n)
+	}
+	cntAllMines(board, m, n, count)
+	dfs(board, m, n, count, y, x)
+	return board
+}
+
+func dfs(board [][]byte, m, n int, count [][]int, y, x int) {
+	if count[y][x] == 0 {
+		board[y][x] = 'B'
+		for dy := -1; dy <= 1; dy++ {
+			for dx := -1; dx <= 1; dx++ {
+				ny, nx := y+dy, x+dx
+				if 0 <= ny && ny < m && 0 <= nx && nx < n && board[ny][nx] == 'E' {
+					dfs(board, m, n, count, ny, nx)
+				}
+			}
+		}
+	} else {
+		board[y][x] = byte(count[y][x] + '0')
+	}
+}
+
+func cntAllMines(board [][]byte, m, n int, count [][]int) {
+	for y := 0; y < m; y++ {
+		for x := 0; x < n; x++ {
+			if board[y][x] == 'M' {
+				for dy := -1; dy <= 1; dy++ {
+					for dx := -1; dx <= 1; dx++ {
+						ny, nx := y+dy, x+dx
+						if 0 <= ny && ny < m && 0 <= nx && nx < n {
+							count[ny][nx]++
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+func updateBoardMLE(board [][]byte, click []int) [][]byte { // BFS, MLE
+	y, x, m, n := click[0], click[1], len(board), len(board[0])
+	if board[y][x] != 'E' {
+		if board[y][x] == 'M' {
+			board[y][x] = 'X'
+		}
+		return board
+	}
+	queue := [][]int{[]int{y, x}}
+	for len(queue) != 0 {
+		y, x = queue[0][0], queue[0][1]
+		queue = queue[1:]
+		cnt := cntMines(board, m, n, y, x)
+		if cnt == 0 {
+			board[y][x] = 'B'
+			for dy := -1; dy <= 1; dy++ {
+				for dx := -1; dx <= 1; dx++ {
+					ny, nx := y+dy, x+dx
+					if 0 <= ny && ny < m && 0 <= nx && nx < n && board[ny][nx] == 'E' {
+						queue = append(queue, []int{ny, nx})
+					}
+				}
+			}
+		} else {
+			board[y][x] = byte(cnt + '0')
+		}
+	}
+	return board
+}
+
+func cntMines(board [][]byte, m, n, y, x int) (cnt int) {
+	for dy := -1; dy <= 1; dy++ {
+		for dx := -1; dx <= 1; dx++ {
+			ny, nx := y+dy, x+dx
+			if 0 <= ny && ny < m && 0 <= nx && nx < n && board[ny][nx] == 'M' {
+				cnt++
+			}
+		}
+	}
+	return
+}

+ 36 - 0
medium/535.encode-and-decode-tinyurl.java

@@ -0,0 +1,36 @@
+public class Codec {
+    private int id = 0;
+    private HashMap<Integer, String> map = new HashMap<>();
+
+    // Encodes a URL to a shortened URL.
+    public String encode(String longUrl) {
+        String[] strs = longUrl.split("//");
+        map.put(id, strs[0] + "/");
+        StringBuilder sb = new StringBuilder();
+        sb.append(id++);
+        String[] body = strs[1].split("/", -1); // -1 means do not discard the last "" string
+        for (String s : body) {
+            map.put(id, s);
+            sb.append(',');
+            sb.append(id++);
+        }
+        return sb.toString();
+    }
+
+    // Decodes a shortened URL to its original URL.
+    public String decode(String shortUrl) {
+        String[] code = shortUrl.split(",");
+        LinkedList<String> list = new LinkedList<>();
+        for (String c : code) {
+            int id = Integer.parseInt(c);
+            String s = map.get(id);
+            list.add(s);
+        }
+        String[] strs = list.toArray(new String[list.size()]);
+        return String.join("/", strs);
+    }
+}
+
+// Your Codec object will be instantiated and called as such:
+// Codec codec = new Codec();
+// codec.decode(codec.encode(url));

+ 9 - 0
medium/537.complex-number-multiplication.go

@@ -0,0 +1,9 @@
+func complexNumberMultiply(a string, b string) string {
+	s1 := strings.Split(a, "+")
+	s2 := strings.Split(b, "+")
+	a1, _ := strconv.Atoi(s1[0])
+	a2, _ := strconv.Atoi(s1[1][:len(s1[1])-1])
+	b1, _ := strconv.Atoi(s2[0])
+	b2, _ := strconv.Atoi(s2[1][:len(s2[1])-1])
+	return fmt.Sprintf("%d+%di", a1*b1-a2*b2, a1*b2+a2*b1)
+}

+ 28 - 0
medium/539.minimum-time-difference.go

@@ -0,0 +1,28 @@
+func findMinDifference(timePoints []string) int {
+	n := len(timePoints)
+	mins := make([]int, n)
+	for i := range mins {
+		mins[i] = time2int(timePoints[i])
+	}
+	sort.Ints(mins)
+	const day int = 24 * 60
+	diff := day
+	for i := 0; i < n-1; i++ {
+		diff = minInt(diff, mins[i+1]-mins[i])
+	}
+	diff = minInt(diff, mins[0]+day-mins[n-1])
+	return diff
+}
+
+func time2int(t string) int {
+	h := int(t[0]*10+t[1]) - 528
+	m := int(t[3]*10+t[4]) - 528
+	return h*60 + m
+}
+
+func minInt(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}

+ 26 - 0
medium/540.single-element-in-a-sorted-array.go

@@ -0,0 +1,26 @@
+func singleNonDuplicate(nums []int) int {
+	n := len(nums)
+	if n == 0 {
+		return 0
+	}
+	beg, end := 0, n-1
+	for beg < end { // Binary search
+		mid := beg + (end-beg)/2
+		if nums[mid] == nums[mid+1] {
+			if (mid-beg)&1 == 1 {
+				end = mid - 1
+			} else {
+				beg = mid + 2
+			}
+		} else {
+			if mid == 0 || nums[mid-1] != nums[mid] {
+				return nums[mid]
+			} else if (end-mid)&1 == 1 {
+				beg = mid + 1
+			} else {
+				end = mid - 2
+			}
+		}
+	}
+	return nums[beg]
+}

+ 53 - 0
medium/542.01-matrix.go

@@ -0,0 +1,53 @@
+var dy []int = []int{0, 1, 0, -1}
+var dx []int = []int{1, 0, -1, 0}
+
+type pair struct {
+	_1 int
+	_2 int
+}
+
+func updateMatrix(matrix [][]int) [][]int {
+	m := len(matrix)
+	if m == 0 {
+		return matrix
+	}
+	n := len(matrix[0])
+	if n == 0 {
+		return matrix
+	}
+	updated := make([][]bool, m)
+	for i := range updated {
+		updated[i] = make([]bool, n)
+	}
+	queue := make([]pair, 0)
+	for y := 0; y < m; y++ {
+		for x := 0; x < n; x++ {
+			if matrix[y][x] == 0 {
+				updated[y][x] = true
+				continue
+			}
+			for i := 0; i < 4; i++ {
+				ny, nx := y+dy[i], x+dx[i]
+				if 0 <= ny && ny < m && 0 <= nx && nx < n && matrix[ny][nx] == 0 {
+					updated[y][x] = true
+					queue = append(queue, pair{y, x})
+					break
+				}
+			}
+		}
+	}
+	for len(queue) != 0 {
+		p := queue[0]
+		queue = queue[1:]
+		val := matrix[p._1][p._2]
+		for i := 0; i < 4; i++ {
+			ny, nx := p._1+dy[i], p._2+dx[i]
+			if 0 <= ny && ny < m && 0 <= nx && nx < n && !updated[ny][nx] {
+				updated[ny][nx] = true
+				queue = append(queue, pair{ny, nx})
+				matrix[ny][nx] = val + 1
+			}
+		}
+	}
+	return matrix
+}

+ 35 - 0
medium/547.friend-circles.go

@@ -0,0 +1,35 @@
+func findCircleNum(M [][]int) int {
+	n := len(M)
+	if n == 0 {
+		return 0
+	}
+	adj := make([][]int, n) // Much faster than the matrix M
+	for i := 0; i < n; i++ {
+		for j := i; j < n; j++ {
+			if M[i][j] == 1 {
+				adj[i] = append(adj[i], j)
+				if i != j {
+					adj[j] = append(adj[j], i)
+				}
+			}
+		}
+	}
+	visited := make([]bool, n)
+	cnt := 0
+	for i := range adj {
+		if !visited[i] && len(adj[i]) != 0 {
+			dfs(adj, &visited, i)
+			cnt++
+		}
+	}
+	return cnt
+}
+
+func dfs(adj [][]int, visited *[]bool, i int) {
+	(*visited)[i] = true
+	for _, v := range adj[i] {
+		if !(*visited)[v] {
+			dfs(adj, visited, v)
+		}
+	}
+}

+ 16 - 0
medium/553.optimal-division.go

@@ -0,0 +1,16 @@
+func optimalDivision(nums []int) string {
+	n := len(nums)
+	if n == 1 { // It's math!
+		return fmt.Sprintf("%d", nums[0])
+	} else if n == 2 {
+		return fmt.Sprintf("%d/%d", nums[0], nums[1])
+	}
+	var sb strings.Builder
+	sb.WriteString(fmt.Sprintf("%d/(%d", nums[0], nums[1]))
+	for i := 2; i < n; i++ {
+		sb.WriteString(fmt.Sprintf("/%d", nums[i]))
+	}
+	sb.WriteRune(')')
+	return sb.String()
+}
+

+ 22 - 0
medium/554.brick-wall.go

@@ -0,0 +1,22 @@
+func leastBricks(wall [][]int) int {
+	cnt := 0
+	freq := make(map[int]int)
+	for i := range wall {
+		left := 0
+		for _, w := range wall[i] {
+			if left != 0 {
+				freq[left]++
+				cnt = maxInt(cnt, freq[left])
+			}
+			left += w
+		}
+	}
+	return len(wall) - cnt
+}
+
+func maxInt(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}

+ 20 - 0
medium/556.next-greater-element-iii.go

@@ -0,0 +1,20 @@
+func nextGreaterElement(n int) int {
+	runes := []rune(strconv.Itoa(n))
+	for n = len(runes) - 2; 0 <= n && runes[n+1] <= runes[n]; n-- {
+	}
+	if n == -1 {
+		return n
+	}
+	i := len(runes) - 1
+	for ; runes[i] <= runes[n]; i-- {
+	}
+	runes[n], runes[i] = runes[i], runes[n]
+	for n, i = n+1, len(runes)-1; n < i; n, i = n+1, i-1 {
+		runes[n], runes[i] = runes[i], runes[n]
+	}
+	n, _ = strconv.Atoi(string(runes))
+	if math.MaxInt32 < n {
+		return -1
+	}
+	return n
+}

+ 15 - 0
medium/560.subarray-sum-equals-k.go

@@ -0,0 +1,15 @@
+func subarraySum(nums []int, k int) int {
+	cnt, n := 0, len(nums)
+	sum := make([]int, n+1)
+	m := make(map[int]int)
+	m[0]++
+	for i := 0; i < n; i++ {
+		s := sum[i] + nums[i]
+		if val, ok := m[s-k]; ok {
+			cnt += val
+		}
+		m[s]++
+		sum[i+1] = s
+	}
+	return cnt
+}

+ 20 - 0
medium/565.array-nesting.go

@@ -0,0 +1,20 @@
+func arrayNesting(nums []int) int {
+	max := 0
+	visited := make([]bool, len(nums))
+	for _, i := range nums {
+		if !visited[i] {
+			cnt := 0
+			for {
+				visited[i] = true
+				cnt, i = cnt+1, nums[i]
+				if visited[i] {
+					break
+				}
+			}
+			if max < cnt {
+				max = cnt
+			}
+		}
+	}
+	return max
+}

+ 44 - 0
medium/567.permutation-in-string.go

@@ -0,0 +1,44 @@
+func checkInclusion(s1 string, s2 string) bool {
+	m, n := len(s1), len(s2)
+	if n < m {
+		return false
+	}
+	freq := make([]int, 256)
+	for _, r := range s1 {
+		freq[r]++
+	}
+	beg, end := 0, -1
+	cnt := make([]int, 256)
+	for end < n {
+		for beg = end + 1; beg < n && freq[s2[beg]] == 0; beg++ {
+		}
+		copy(cnt, freq)
+		for end = beg; end < n; end++ {
+			ch := s2[end]
+			if freq[ch] == 0 {
+				break
+			}
+			cnt[ch]--
+			for cnt[ch] < 0 {
+				cnt[s2[beg]]++
+				beg++
+			}
+			if isEmpty(cnt) {
+				return true
+			}
+		}
+	}
+	if isEmpty(cnt) {
+		return true
+	}
+	return false
+}
+
+func isEmpty(cnt []int) bool {
+	for i := 'a'; i <= 'z'; i++ {
+		if cnt[i] != 0 {
+			return false
+		}
+	}
+	return true
+}

+ 26 - 0
medium/576.out-of-boundary-paths.go

@@ -0,0 +1,26 @@
+const MOD int = 1000000007
+
+var dy = []int{0, 1, 0, -1}
+var dx = []int{1, 0, -1, 0}
+
+func findPaths(m int, n int, N int, i int, j int) int {
+	var dp [50][50]int
+	for k := 0; k < N; k++ {
+		var nxt [50][50]int
+		for y := 0; y < m; y++ {
+			for x := 0; x < n; x++ {
+				for d := 0; d < 4; d++ {
+					ny, nx := y+dy[d], x+dx[d]
+					if ny == -1 || ny == m || nx == -1 || nx == n {
+						nxt[y][x]++
+					} else {
+						nxt[y][x] = (nxt[y][x] + dp[ny][nx]) % MOD
+					}
+				}
+			}
+		}
+		dp = nxt
+	}
+	return dp[i][j]
+}
+

+ 27 - 0
medium/583.delete-operation-for-two-strings.go

@@ -0,0 +1,27 @@
+func minDistance(word1 string, word2 string) int {
+	// dp[i][j] means the LCS of s1[0:i] && s2[0:j],
+	// then if s1[i] == s2[j], dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j]+1)
+	// else dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j])
+	m, n := len(word1), len(word2)
+	dp := make([][]int, m+1)
+	for i := range dp {
+		dp[i] = make([]int, n+1)
+	}
+	for i := range word1 {
+		for j := range word2 {
+			if word1[i] == word2[j] {
+				dp[i+1][j+1] = maxInt(dp[i+1][j+1], dp[i][j]+1)
+			} else {
+				dp[i+1][j+1] = maxInt(dp[i][j+1], dp[i+1][j])
+			}
+		}
+	}
+	return m + n - 2*dp[m][n]
+}
+
+func maxInt(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}

+ 49 - 0
medium/592.fraction-addition-and-subtraction.go

@@ -0,0 +1,49 @@
+type pair struct {
+	_1 int
+	_2 int
+}
+
+func (p1 *pair) add(p2 pair) {
+	if p1._1 == 0 {
+		*p1 = p2
+	} else {
+		p1._1 = p1._1*p2._2 + p2._1*p1._2
+		p1._2 *= p2._2
+	}
+}
+
+func fractionAddition(expression string) string {
+	beg, end, n := 0, 1, len(expression)
+	var sum pair
+	for end < n {
+		for end = beg + 1; end < n && expression[end] != '+' && expression[end] != '-'; end++ {
+		}
+		p := str2frac(expression[beg:end])
+		sum.add(p)
+		beg = end
+	}
+	i := gcd(abs(sum._1), sum._2)
+	return fmt.Sprintf("%d/%d", sum._1/i, sum._2/i)
+}
+
+func gcd(a, b int) int {
+	if b == 0 {
+		return a
+	}
+	return gcd(b, a%b)
+}
+
+func str2frac(s string) (p pair) {
+	strs := strings.Split(s, "/")
+	p._1, _ = strconv.Atoi(strs[0])
+	p._2, _ = strconv.Atoi(strs[1])
+	return
+}
+
+func abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}
+

+ 23 - 0
medium/593.valid-square.go

@@ -0,0 +1,23 @@
+func validSquare(p1 []int, p2 []int, p3 []int, p4 []int) bool {
+	seg := make(map[int]int)
+	seg[dist2(p1, p2)]++
+	seg[dist2(p1, p3)]++
+	seg[dist2(p1, p4)]++
+	seg[dist2(p2, p3)]++
+	seg[dist2(p2, p4)]++
+	seg[dist2(p3, p4)]++
+	if len(seg) != 2 {
+		return false
+	}
+	for _, v := range seg {
+		if v&1 == 1 {
+			return false
+		}
+	}
+	return true
+}
+
+func dist2(p1, p2 []int) int {
+	dx, dy := p1[0]-p2[0], p1[1]-p2[1]
+	return dx*dx + dy*dy
+}