Leetcode Practice
Array
704. Binary Search
func search(nums []int, target int) int {
left, right := 0, len(nums)-1
for left <= right{
mid := (right - left) >> 1 + left
if nums[mid] == target{
return mid
}else if nums[mid] < target {
left = mid + 1
}else{
right = mid - 1
}
}
return -1
}
Find The Single Number
Example 1
input: nums = [2,2,3,3,4]
output: 4
Example 2
input: nums = [2,2,3,3,5,7,7,8,8]
output: 5
nums.length >= 3
func solution(nums []int) int {
if len(nums) < 3 {
return -1
}
left, right := 0, len(nums)-1
for left+3 < right {
mid := left + (right-left)>>1
if mid%2 == 1 {
if nums[mid] == nums[mid+1] {
right = mid - 1
} else if nums[mid] == nums[mid-1] {
left = mid + 1
} else {
return nums[mid]
}
} else {
if nums[mid] == nums[mid-1] {
right = mid - 2
} else if nums[mid] == nums[mid+1] {
left = mid + 2
} else {
return nums[mid]
}
}
}
if left == 0 {
return nums[left]
}
if right == len(nums)-1 {
return nums[right]
}
return -1
}
34. Find First and Last Position of Element in Sorted Array
func searchRange(nums []int, target int) []int {
res := []int{-1, -1}
if len(nums) == 0{
return res
}
left, right := 0, len(nums) - 1
for left <= right{
mid := left + (right-left)>>1
if nums[mid] >= target{
right = mid - 1
} else {
left = mid + 1
}
}
// 5 7 7 8 8 10
// right left
if left <= len(nums) - 1 && nums[left] == target{
res[0] = left
}
left, right = 0, len(nums) - 1
for left <= right{
mid := left + (right-left)>>1
if nums[mid] <= target{
left = mid + 1
}else {
right = mid - 1
}
}
// 5 7 7 8 8 10
// right left
if right >= 0 && nums[right] == target{
res[1] = right
}
return res
}
27. Remove Element
// 方法一
func removeElement(nums []int, val int) int {
left, right := 0, len(nums) - 1
for left <= right{
if nums[left] == val {
if nums[right] != val{
nums[left], nums[right] = nums[right], nums[left]
left++
right--
}else{
right--
}
}else{
if nums[right] != val{
left ++
}else{
right--
left ++
}
}
}
return right+1
}
// 方法二
// 快慢指针
// 新数组比旧数组短,从左填充
// String部分的Replace Space,新数组比旧数组长,从右填充
func removeElement(nums []int, val int) int {
left := 0
for _, v := range nums{
if v != val{
nums[left] = v
left++
}
}
return left
}
977. Squares of a Sorted Array
// 方法一
func sortedSquares(nums []int) []int {
res := make([]int, len(nums))
left, right, k := 0, len(nums)-1, len(nums)-1
for ; left <= right; k-- {
if nums[left] * nums[left] > nums[right] * nums[right]{
res[k] = nums[left] * nums[left]
left++
}else{
res[k] = nums[right] * nums[right]
right--
}
}
return res
}
// 方法二
func sortedSquares(nums []int) []int {
for i, value := range nums {
nums[i] = value * value
}
sort.Ints(nums)
return nums
}
209. Minimum Size Subarray Sum
func minSubArrayLen(target int, nums []int) int {
left, sum, res := 0, 0, len(nums) + 1
for right, v := range nums{
sum += v
for sum >= target{
res = min(res, right - left + 1)
sum -= nums[left]
left ++
}
}
if res == len(nums) + 1{
res = 0
}
return res
}
func min(a, b int)int{
if a <= b{
return a
}
return b
}
59. Spiral Matrix II
func generateMatrix(n int) [][]int {
top, bottom := 0, n-1
left, right := 0, n-1
num := 1
tar := n * n
matrix := make([][]int, n)
for i := 0; i < n; i++ {
matrix[i] = make([]int, n)
}
for num <= tar {
for i := left; i <= right; i++ {
matrix[top][i] = num
num++
}
top++
for i := top; i <= bottom; i++ {
matrix[i][right] = num
num++
}
right--
for i := right; i >= left; i-- {
matrix[bottom][i] = num
num++
}
bottom--
for i := bottom; i >= top; i-- {
matrix[i][left] = num
num++
}
left++
}
return matrix
}
3. Longest Substring Without Repeating Characters
func lengthOfLongestSubstring(s string) int {
m := make(map[rune]int)
left, res := 0, 0
for right, v := range s{
if v2, ok := m[v]; ok && left <= v2{
left = v2 + 1
}
m[v] = right
if v3 := right - left + 1; v3 > res{
res = v3
}
}
return res
}
35. Search Insert Position
// 方法一
func searchInsert(nums []int, target int) int {
left := 0
right := len(nums)-1
for left <= right {
mid := left + (right - left) / 2 // 防求和溢出
if nums[mid] == target {
return mid
}else if nums[mid] > target{
right = mid - 1
}else{
left = mid + 1
}
}
// 此时 right + 1 == left
// nums[right] < target < nums[left]
return left
}
// 方法二
// nums[right] is the biggest number less than the target
func searchInsert(nums []int, target int) int {
left, right := 0, len(nums)-1
for left <= right {
mid := left + (right-left)>>1
if nums[mid] >= target {
right = mid - 1
} else {
left = mid + 1
}
}
return right+1
}
283. Move Zeroes
func moveZeroes(nums []int) {
if len(nums) == 0{
return
}
left := 0
for right, v := range nums{
if v != 0{
nums[right] = 0
nums[left] = v
left++
}
}
}
func moveZeroes(nums []int) {
// j stay on the index of zero
j := 0
for i := 0; i < len(nums); i++ {
if nums[i] != 0 {
if i != j {
nums[i], nums[j] = nums[j], nums[i]
j++
} else {
j++
}
}
}
}
881. Boats to Save People
import (
"sort"
)
func numRescueBoats(people []int, limit int) int {
sort.Ints(people)
left, right, res := 0, len(people)-1, 0
for left <= right {
if left == right {
res++
return res
}
if people[left]+people[right] <= limit {
left++
right--
} else {
right--
}
res++
}
return res
}
304. Range Sum Query 2D - Immutable
type NumMatrix struct {
preSum [][]int
}
func Constructor(matrix [][]int) NumMatrix {
m := len(matrix)
n := len(matrix[0])
preSum := make([][]int, m+1)
for i := 0; i < m+1; i++{
preSum[i] = make([]int, n+1)
}
for i := 0; i < m; i++{
for j := 0; j < n; j++{
// matrix[i][j] = preSum[i+1][j+1] - (preSum[i][j+1] - preSum[i+1][j] + preSum[i][j])
preSum[i+1][j+1] = preSum[i][j+1] + preSum[i+1][j] - preSum[i][j] + matrix[i][j]
}
}
return NumMatrix{preSum:preSum}
}
func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
preSum := this.preSum
return preSum[row2+1][col2+1] - preSum[row2+1][col1] - preSum[row1][col2+1] + preSum[row1][col1]
}
Linked List
删反交换交点环
203. Remove Linked List Elements
func removeElements(head *ListNode, val int) *ListNode {
preHead := new(ListNode)
preHead.Next = head
pre := preHead
cur := head
for cur != nil{
if cur.Val == val{
pre.Next = cur.Next
cur = cur.Next
}else{
pre = cur
cur = cur.Next
}
}
return preHead.Next
}
19. Remove Nth Node From End of List
// cur.Next=nil, 倒数第1个节点
// cur.Next.Next=nil, 倒数第2个节点
// 按规律找出倒数第n+1个节点
func removeNthFromEnd(head *ListNode, n int) *ListNode {
preHead := new(ListNode)
preHead.Next = head
left := preHead
right := preHead
for i := 0; i < n+1; i++{
right = right.Next
}
for right != nil{
right = right.Next
left = left.Next
}
left.Next = left.Next.Next
return preHead.Next
}
206. Reverse Linked List
func reverseList(head *ListNode) *ListNode {
var pre *ListNode
cur := head
for cur != nil{
cur.Next, pre, cur = pre, cur, cur.Next
}
return pre
}
24. Swap Nodes in Pairs
// 递归
func swapPairs(head *ListNode) *ListNode {
if head == nil || head.Next == nil{
return head
}
newHead := head.Next
head.Next.Next, head.Next = head, swapPairs(head.Next.Next)
return newHead
}
// 迭代
func swapPairs(head *ListNode) *ListNode {
preHead := new(ListNode)
preHead.Next = head
cur := preHead
for cur.Next != nil && cur.Next.Next != nil{
cur.Next,
cur.Next.Next.Next,
cur.Next.Next,
cur =
cur.Next.Next,
cur.Next,
cur.Next.Next.Next,
cur.Next
// cur, cur.Next, cur.Next.Next, cur.Next.Next.Next =
// cur.Next, cur.Next.Next, cur.Next.Next.Next, cur.Next
}
return preHead.Next
}
Intersection of Two Linked Lists LCCI
func getIntersectionNode(headA, headB *ListNode) *ListNode {
curA, curB := headA, headB
lengtA, lengtB := 0, 0
for curA != nil{
lengtA++
curA = curA.Next
}
for curB != nil{
lengtB++
curB = curB.Next
}
curA, curB = headA, headB
if lengtA < lengtB{
lengtA, lengtB = lengtB, lengtA
curA, curB = curB, curA
}
for i := 0; i < lengtA-lengtB; i++{
curA = curA.Next
}
for i := 0; i < lengtB; i++{
if curA == curB{
return curA
}
curA = curA.Next
curB = curB.Next
}
return nil
}
142. Linked List Cycle II
fast: $ t = (x_{1} + x_{2} + x_{3} + x_{2}) \div 2 $
slow: $ t = (x_{1} + x_{2}) \div 1 $
$ x_{1} + x_{2} + x_{3} + x_{2} = (x_{1} + x_{2}) \times 2 \Longrightarrow x_{1} = x_{3} $
func detectCycle(head *ListNode) *ListNode {
if head == nil|| head.Next == nil{
return nil
}
intersection := findIntersection(head)
// no circle
if intersection == nil{
return nil
}
fast := head
slow := intersection
for fast != slow {
fast = fast.Next
slow = slow.Next
}
return slow
}
func findIntersection(head *ListNode) *ListNode{
fast, slow := head, head
for slow != nil && fast != nil && fast.Next != nil{
fast = fast.Next.Next
slow = slow.Next
if slow == fast{
return slow
}
}
return nil
}
Hash Table
242. Valid Anagram
func isAnagram(s string, t string) bool {
m := make(map[rune]int)
for _, v := range s{
m[v] ++
}
for _, v := range t{
m[v] --
}
for _, v := range m{
if v != 0{
return false
}
}
return true
}
383. Ransom Note
func canConstruct(ransomNote string, magazine string) bool {
m := make(map[rune]int)
for _, v := range ransomNote{
m[v]++
}
for _, v := range magazine{
if _, ok := m[v]; ok{
m[v]--
}
}
for _, v := range m{
if v > 0{
return false
}
}
return true
}
349. Intersection of Two Arrays
func intersection(nums1 []int, nums2 []int) []int {
m := make(map[int]bool)
var res []int
for _, n := range nums1 {
m[n] = true
}
for _, n := range nums2 {
if m[n] {
//delete(m, n)
m[n] = false
res = append(res, n)
}
}
return res
}
202. Happy Number
func isHappy(n int) bool {
m := make(map[int]bool)
for n != 1{
if m[n]{
return false
}
m[n] = true
n = calcu(n)
}
return true
}
func calcu(n int)int{
sum := 0
for n != 0{
rem := n % 10
sum = sum + rem*rem
n = n / 10
}
return sum
}
1. Two Sum
func twoSum(nums []int, target int) []int {
m := make(map[int]int)
for k, v := range nums{
if v2, ok := m[target-v]; ok{
return []int{v2, k}
}else{
m[v] = k
}
}
return nil
}
15. 3Sum
import "sort"
func threeSum(nums []int) [][]int {
res := make([][]int, 0)
sort.Ints(nums)
length := len(nums)
for i := 0; i < length; i++{
// De-duplication
// same with last element
if i > 0 && nums[i] == nums[i-1]{
continue
}
left, right := i+1, length-1
for left < right{
sum := nums[i] + nums[left] + nums[right]
if sum < 0{
left++
}else if sum > 0{
right--
}else{
res = append(res, []int{nums[i], nums[left], nums[right]})
for left < right && nums[right] == nums[right-1]{
right--
}
for left < right && nums[left] == nums[left+1]{
left++
}
right--
left++
}
}
}
return res
}
func threeSum(nums []int) [][]int {
res := make([][]int, 0)
sort.Ints(nums)
for i := 0; i < len(nums); i++{
if i > 0 && nums[i] == nums[i-1]{
continue
}
left, right := i+1, len(nums)-1
CHECK:
for left < right{
for left > i+1 && nums[left] == nums[left-1]{
left++
continue CHECK
}
for right < len(nums) - 1 && nums[right] == nums[right+1]{
right--
continue CHECK
}
if nums[i] + nums[left] + nums[right] == 0{
res = append(res, []int{nums[i], nums[left], nums[right]})
left++
right--
}else if nums[i] + nums[left] + nums[right] < 0{
left++
}else{
right--
}
}
}
return res
}
18. 4Sum
import "sort"
func fourSum(nums []int, target int) [][]int {
sort.Ints(nums)
length := len(nums)
res := [][]int{}
for i := 0; i < length; i++{
if i > 0 && nums[i] == nums[i-1]{
continue
}
for j := i+1; j < length; j++{
if j > i+1 && nums[j] == nums[j-1]{
continue
}
left, right := j+1, length-1
CHECK:
for left < right{
for left > j+1 && nums[left] == nums[left-1]{
left++
continue CHECK
}
for right < length-1 && nums[right] == nums[right+1]{
right--
continue CHECK
}
sum := nums[i] + nums[j] + nums[left] + nums[right]
if sum > target{
right--
}else if sum < target{
left++
}else{
res = append(res, []int{nums[i], nums[j], nums[left], nums[right]})
left++
right--
}
}
}
}
return res
}
454. 4Sum II
func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {
m := make(map[int]int, len(nums1)*len(nums2))
for _, v := range nums1{
for _, v2 := range nums2{
m[v+v2] ++
}
}
res := 0
for _, v3 := range nums3{
for _, v4 := range nums4{
res += m[0-v3-v4]
}
}
return res
}
String
344. Reverse String
func reverseString(s []byte) {
left, right := 0, len(s)-1
for left < right{
s[left], s[right] = s[right], s[left]
left++
right--
}
}
541. Reverse String II
func reverseStr(s string, k int) string {
b := []byte(s)
length := len(b)
for i := 0; i < length; i += 2*k{
end := i+k
if end > length{
end = length
}
reverse(b[i:end])
}
return string(b)
}
func reverse(s []byte) {
left, right := 0, len(s)-1
for left < right{
s[left], s[right] = s[right], s[left]
left++
right--
}
}
Replace Space
func replaceSpace(s string) string {
count := 0
for _, v := range s{
if v == ' '{
count++
}
}
b := make([]byte, len(s)+2*count)
right := 0
for _, v := range s{
if v == ' '{
b[right] = '%'
b[right+1] = '2'
b[right+2] = '0'
right += 3
continue
}
b[right] = byte(v)
right++
}
return string(b)
}
func replaceSpace(s string) string {
b := []byte(s)
left := len(b)-1
count := 0
for i := 0; i <= left; i++{
if b[i] == byte(' '){
count++
}
}
padding := make([]byte, 2*count)
b = append(b, padding...)
right := len(b)-1
for left < right{
if b[left] == byte(' '){
b[right] = '0'
b[right-1] = '2'
b[right-2] = '%'
right -= 3
left--
continue
}
b[right] = b[left]
right--
left--
}
return string(b)
}
151. Reverse Words in a String
// method 1
func reverseWords(s string) string {
ss := strings.Fields(s)
reverse(ss)
return strings.Join(ss, " ")
}
func reverse(m []string) {
i := 0
j := len(m)-1
for i < j {
m[i], m[j] = m[j], m[i]
i++
j--
}
}
// method 2
func reverseWords(s string) string {
b := []byte(s)
b = removeExtraSpaces(b)
reverse(b)
wordstart := 0
for k, v := range b{
if k == len(b)-1{
reverse(b[wordstart:])
}
if v == ' ' {
reverse(b[wordstart: k])
wordstart = k + 1
}
}
return string(b)
}
func removeExtraSpaces(b []byte) []byte{
fast := 0
for fast < len(b) && b[fast] == ' '{
fast++
}
slow := 0
for ; fast < len(b); fast++{
cond1 := b[fast] != ' '
cond2 := b[fast] == ' ' && fast > 0 && b[fast-1] != ' '
if cond1 || cond2{
b[slow] = b[fast]
slow++
}
}
if b[slow-1] == ' '{
return b[:slow-1]
}else{
return b[:slow]
}
}
28. Implement strStr()
// 方法一:KMP
// H: AABAACAABAACAABAAD
// N: AABAACAABAAD
// i是haystack下标,j是needle的下标
// H[0:11] == N[0:11], 前11次比较匹配
// 第12次比较不匹配,即i = j = 11时,H[11] != N[11]
// 由 j = next[j-1] = next(11-1) = 5,表示前5次比较是匹配的
// 也就是 H[6:11] == N[0:5]
// 因此可以直接从H[11] 与 N[5]开始比较,H的遍历过程没有回退
// 复杂度O(n)
func strStr(haystack string, needle string) int {
next := getNext(needle)
j := 0
for i := 0; i < len(haystack); i++ {
for j > 0 && haystack[i] != needle[j] {
j = next[j-1]
}
if haystack[i] == needle[j] {
j++
}
if j == len(needle) {
return i - j + 1
}
}
return -1
}
// needle: a d c a d d e
// next: 0 0 0 1 2 0 0
// needle: a a b a a f
// next: 0 1 0 1 2 0
func getNext(needle string) []int {
next := make([]int, len(needle))
next[0] = 0
for right := 1; right < len(needle); right++ {
//
left := next[right-1]
for left > 0 && needle[right] != needle[left] {
left = next[left-1]
}
if needle[right] == needle[left] {
left++
}
next[right] = left
}
return next
}
// 方法二
func strStr(haystack string, needle string) int {
if needle == ""{
return 0
}
for i, j := 0, len(needle); j <= len(haystack); i, j = i+1, j+1{
if haystack[i:j] == needle{
return i
}
}
return -1
}
459. Repeated Substring Pattern
func repeatedSubstringPattern(s string) bool {
for i := 1; i < len(s)/2 + 1; i++{
if len(s) % i != 0{
continue
}
for j := 1; j < len(s)/i; j++{
if s[0:i] != s[j*i:j*i+i]{
break
}
// 成功匹配最后一段
if j == len(s)/i -1 {
return true
}
}
}
return false
}
//KMP
func repeatedSubstringPattern(s string) bool {
if len(s) < 2{
return false
}
next := getNext(s)
a := next[len(s)-1] // 最长相同前后缀的长度
b := len(s) - a // 重复子串长度
if a > 0 && len(s) % b == 0{
return true
}
return false
}
func getNext(needle string) []int {
next := make([]int, len(needle))
next[0] = 0
for right := 1; right < len(needle); right++ {
left := next[right-1]
for left > 0 && needle[right] != needle[left] {
left = next[left-1]
}
if needle[right] == needle[left] {
left++
}
next[right] = left
}
return next
}
Stack and Queue
20. Valid Parentheses
func isValid(s string) bool {
stack := make([]rune, 0)
for _, v := range s{
switch v{
case '(':
stack = append(stack, ')')
case '[':
stack = append(stack, ']')
case '{':
stack = append(stack, '}')
default:
if len(stack) > 0 && stack[len(stack)-1] == v{
stack = stack[:len(stack)-1] // 出栈
}else{
return false
}
}
}
return len(stack) == 0
}
1047. Remove All Adjacent Duplicates In String
func removeDuplicates(s string) string {
stack := make([]rune, 0)
for _, v := range s{
if len(stack) > 0 && stack[len(stack)-1] == v{
stack = stack[:len(stack)-1]
}else{
stack = append(stack, v)
}
}
return string(stack)
}
150. Evaluate Reverse Polish Notation
func evalRPN(tokens []string) int {
var stack []int
for _, v := range tokens{
switch v{
case "+":
stack[len(stack)-2] = stack[len(stack)-2] + stack[len(stack)-1]
stack = stack[:len(stack)-1]
case "-":
stack[len(stack)-2] = stack[len(stack)-2] - stack[len(stack)-1]
stack = stack[:len(stack)-1]
case "*":
stack[len(stack)-2] = stack[len(stack)-2] * stack[len(stack)-1]
stack = stack[:len(stack)-1]
case "/":
stack[len(stack)-2] = stack[len(stack)-2] / stack[len(stack)-1]
stack = stack[:len(stack)-1]
default:
v2, _ := strconv.Atoi(v)
stack = append(stack, v2)
}
}
return stack[0]
}
239. Sliding Window Maximum
func maxSlidingWindow(nums []int, k int) []int {
queue := make([]int, 0)
res := make([]int, 0)
for i, v := range nums{
// 处理离开窗口的元素
if i >= k && nums[i-k] == queue[0]{
queue = queue[1:]
}
// 处理进入窗口的元素
for len(queue) > 0 && v > queue[len(queue)-1]{
queue = queue[0:len(queue)-1]
}
queue = append(queue, v)
// 记录窗口最大值
if i >= k-1 {
res = append(res, queue[0])
}
}
return res
}
347. Top K Frequent Elements
import "sort"
func topKFrequent(nums []int, k int) []int {
m := make(map[int]int)
for _, num := range nums{
m[num]++
}
keys := []int{}
for key, _ := range m{
keys = append(keys, key)
}
sort.Slice(keys, func(i, j int)bool{
return m[keys[i]] > m[keys[j]]
})
return keys[:k]
}
Binary Tree
94. 144. 145. Binary Tree Traversal
👉 LeetCode Preorder
👉 LeetCode Inorder
👉 LeetCode Postorder
//type TreeNode struct {
// Val int
// Left *TreeNode
// Right *TreeNode
//}
// 递归法
func preorderTraversal(root *TreeNode) []int {
res := []int{}
var rec func(*TreeNode)
rec = func(node *TreeNode){
if node == nil{
return
}
res = append(res, node.Val)
rec(node.Left)
rec(node.Right)
}
rec(root)
return res
}
func inorderTraversal(root *TreeNode) []int {
res := []int{}
var rec func(*TreeNode)
rec = func(node *TreeNode){
if node == nil{
return
}
rec(node.Left)
res = append(res, node.Val)
rec(node.Right)
}
rec(root)
return res
}
func postorderTraversal(root *TreeNode) []int {
res := []int{}
var rec func(*TreeNode)
rec = func(node *TreeNode){
if node == nil{
return
}
rec(node.Left)
rec(node.Right)
res = append(res, node.Val)
}
rec(root)
return res
}
// 迭代法
func preorderTraversal(root *TreeNode) []int {
res := make([]int, 0)
stack := make([]*TreeNode, 0)
if root != nil{
stack = append(stack, root)
}
for len(stack) > 0 {
// 出栈
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if node != nil{
// 右入栈
if node.Right != nil{
stack = append(stack, node.Right)
}
// 左入栈
if node.Left != nil{
stack = append(stack, node.Left)
}
// 中入栈
// 再次入栈时后面加一个读标记
stack = append(stack, node, nil)
}else{
// 读取数据
res = append(res, stack[len(stack)-1].Val)
stack = stack[:len(stack)-1]
}
}
return res
}
func inorderTraversal(root *TreeNode) []int {
res := make([]int, 0)
stack := make([]*TreeNode, 0)
if root != nil{
stack = append(stack, root)
}
for len(stack) > 0 {
// 出栈
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if node != nil{
// 右入栈
if node.Right != nil{
stack = append(stack, node.Right)
}
// 中入栈
// 再次入栈时后面加一个读标记
stack = append(stack, node, nil)
// 左入栈
if node.Left != nil{
stack = append(stack, node.Left)
}
}else{
res = append(res, stack[len(stack)-1].Val)
stack = stack[:len(stack)-1]
}
}
return res
}
func inorderTraversal(root *TreeNode) []int {
res := make([]int, 0)
stack := make([]*TreeNode, 0)
node := root
for node != nil || len(stack) > 0 {
for node != nil{
stack = append(stack, node)
node = node.Left
}
node = stack[len(stack)-1]
stack = stack[:len(stack)-1]
res = append(res, node.Val)
node = node.Right
}
return res
}
func postorderTraversal(root *TreeNode) []int {
res := make([]int, 0)
stack := make([]*TreeNode, 0)
if root != nil{
stack = append(stack, root)
}
for len(stack) > 0 {
// 出栈
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if node != nil{
// 再次入栈时后面加一个标记
stack = append(stack, node, nil)
if node.Right != nil{
stack = append(stack, node.Right)
}
if node.Left != nil{
stack = append(stack, node.Left)
}
}else{
res = append(res, stack[len(stack)-1].Val)
stack = stack[:len(stack)-1]
}
}
return res
}
102. Binary Tree Level Order Traversal
func levelOrder(root *TreeNode) [][]int {
queue := make([]*TreeNode, 0)
if root != nil{
queue = append(queue, root)
}
res := make([][]int, 0)
for len(queue) > 0{
row := make([]int, 0)
// 每层节点的数量
n := len(queue)
// 同层的节点都出队列
// 出队列的同时把下一层的节点加入队列
for i := 0; i < n; i++{
node := queue[0]
queue = queue[1:]
row = append(row, node.Val)
if node.Left != nil{
queue = append(queue, node.Left)
}
if node.Right != nil{
queue = append(queue, node.Right)
}
}
res = append(res, row)
}
return res
}
107. Binary Tree Level Order Traversal II
func levelOrderBottom(root *TreeNode) [][]int {
queue := make([]*TreeNode, 0)
if root != nil{
queue = append(queue, root)
}
res := make([][]int, 0)
for len(queue) > 0{
// ...
}
i, j := 0, len(res)-1
for i < j{
res[i], res[j] = res[j], res[i]
i++
j--
}
return res
}
104. Maximum Depth of Binary Tree
// 递归,分解问题
func maxDepth(root *TreeNode) int {
if root == nil{
return 0
}
maxLeft := maxDepth(root.Left)
maxRight := maxDepth(root.Right)
if maxLeft > maxRight{
return maxLeft + 1
}
return maxRight + 1
}
// 递归,遍历二叉树
func maxDepth(root *TreeNode) int {
res, deepth := 0, 0
var rec func(*TreeNode)
rec = func(root *TreeNode){
if root == nil{
if deepth > res{
res = deepth
}
return
}
deepth++
rec(root.Left)
// deepth--
// deepth++
rec(root.Right)
deepth--
}
rec(root)
return res
}
// 迭代法, 遍历二叉树
func maxDepth(root *TreeNode) int {
queue := make([]*TreeNode, 0)
if root != nil{
queue = append(queue, root)
}
res := 0
for len(queue) > 0{
res++
// 每层节点的数量
n := len(queue)
// 同层的节点都出队列
// 出队列的同时把下一层的节点加入队列
for i := 0; i < n; i++{
node := queue[0]
queue = queue[1:]
if node.Left != nil{
queue = append(queue, node.Left)
}
if node.Right != nil{
queue = append(queue, node.Right)
}
}
}
return res
}
111. Minimum Depth of Binary Tree
func minDepth(root *TreeNode) int {
queue := make([]*TreeNode, 0)
if root != nil{
queue = append(queue, root)
}
res := 0
for len(queue) > 0{
res++
// 每层节点的数量
n := len(queue)
// 同层的节点都出队列
// 出队列的同时把下一层的节点加入队列
for i := 0; i < n; i++{
node := queue[0]
queue = queue[1:]
if node.Left == nil && node.Right == nil{
return res
}
if node.Left != nil{
queue = append(queue, node.Left)
}
if node.Right != nil{
queue = append(queue, node.Right)
}
}
}
return res
}
226. Invert Binary Tree
把每一个节点的左右孩子交换一下
// 分解问题
func invertTree(root *TreeNode) *TreeNode {
if root == nil{
return nil
}
l := invertTree(root.Left)
r := invertTree(root.Right)
root.Left, root.Right = r, l
return root
}
// 递归遍历
func invertTree(root *TreeNode) *TreeNode {
var rec func(*TreeNode)
rec = func(node *TreeNode){
if node == nil{
return
}
rec(node.Left)
rec(node.Right)
node.Left, node.Right = node.Right, node.Left
}
rec(root)
return root
}
// 迭代遍历
func invertTree(root *TreeNode) *TreeNode {
queue := make([]*TreeNode, 0)
if root != nil{
queue = append(queue, root)
}
for len(queue) > 0{
node := queue[0]
queue = queue[1:]
if node.Left != nil{
queue = append(queue, node.Left)
}
if node.Right != nil{
queue = append(queue, node.Right)
}
node.Left, node.Right = node.Right, node.Left
}
return root
}
101. Symmetric Tree
// 递归
func isSymmetric(root *TreeNode) bool {
var rec func(left, right *TreeNode)bool
rec = func(left, right *TreeNode)bool{
if left == nil && right == nil{
return true
}else if left == nil && right != nil{
return false
}else if left != nil && right == nil{
return false
}else if left != nil && right != nil && left.Val != right.Val{
return false
}
// 匹配外侧,匹配内侧
if rec(left.Left, right.Right) && rec(left.Right, right.Left){
return true
}
return false
}
return rec(root.Left, root.Right)
}
// 迭代
func isSymmetric(root *TreeNode) bool {
queue := make([]*TreeNode, 0)
if root != nil{
queue = append(queue, root.Left, root.Right)
}
for len(queue) > 0{
l, r := queue[0], queue[1]
queue = queue[2:]
if l == nil && r == nil{
continue
}else if l == nil && r != nil || l != nil && r == nil ||
l != nil && r != nil && l.Val != r.Val{
return false
}
queue = append(queue, l.Left)
queue = append(queue, r.Right)
queue = append(queue, l.Right)
queue = append(queue, r.Left)
}
return true
}
110. Balanced Binary Tree
func isBalanced(root *TreeNode) bool {
var getDepth func(*TreeNode) int
getDepth = func(node *TreeNode) int{
if node == nil{
return 0
}
ld, rd := getDepth(node.Left), getDepth(node.Right)
// 不平衡时返回-1
if ld < 0 || rd < 0 || ld - rd > 1 || rd - ld > 1{
return -1
}
if ld > rd{
return ld + 1
}
return rd + 1
}
return getDepth(root) > -1
}
257. Binary Tree Paths
// dfs
func binaryTreePaths(root *TreeNode) []string {
res := make([]string, 0)
var rec func(*TreeNode, string)
rec = func(node *TreeNode, path string){
if node == nil{
return
}
path += "->" + strconv.Itoa(node.Val)
if node.Left == nil && node.Right == nil{
res = append(res, path[2:])
return
}
rec(node.Left, path)
rec(node.Right, path)
}
rec(root, "")
return res
}
// bfs
func binaryTreePaths(root *TreeNode) []string {
res := make([]string, 0)
queue := make([]*TreeNode, 0)
paths := make([]string, 0)
if root != nil{
queue = append(queue, root)
paths = append(paths, strconv.Itoa(root.Val))
}
for len(queue) > 0{
node := queue[0]
queue = queue[1:]
path := paths[0]
paths = paths[1:]
if node != nil{
// 叶节点完成一个path
if node.Left == nil && node.Right == nil{
res = append(res, path)
}
if node.Right != nil{
queue = append(queue, node.Right)
paths = append(paths, path + "->" + strconv.Itoa(node.Right.Val))
}
if node.Left != nil{
queue = append(queue, node.Left)
paths = append(paths, path + "->" + strconv.Itoa(node.Left.Val))
}
}
}
return res
}
404. Sum of Left Leave
func sumOfLeftLeaves(root *TreeNode) int {
sum := 0
var rec func(*TreeNode)
rec = func(root *TreeNode){
if root == nil{
return
}
if root != nil && root.Left != nil &&
root.Left.Left == nil && root.Left.Right == nil{
sum += root.Left.Val
}
rec(root.Left)
rec(root.Right)
}
rec(root)
return sum
}
func sumOfLeftLeaves(root *TreeNode) int {
res := 0
queue := make([]*TreeNode, 0)
if root != nil{
queue = append(queue, root)
}
for len(queue) > 0{
node := queue[0]
queue = queue[1:]
if node != nil{
if node.Right != nil{
queue = append(queue, node.Right)
}
if node.Left != nil{
// 是左节点
if node.Left.Left == nil && node.Left.Right == nil{
res += node.Left.Val
}else{
queue = append(queue, node.Left)
}
}
}
}
return res
}
113. Path Sum II
func pathSum(root *TreeNode, targetSum int) [][]int {
res := make([][]int, 0)
var rec func(*TreeNode, []int, int)
rec = func(node *TreeNode, path []int, sum int){
if node == nil{
return
}
path = append(path, node.Val)
sum -= node.Val
if node.Left == nil && node.Right == nil && sum == 0{
res = append(res,append([]int{}, path...)) // 这里需要拷贝
}
rec(node.Left, path, sum)
rec(node.Right, path, sum)
}
rec(root, []int(nil), targetSum)
return res
}
106. Construct Binary Tree from Inorder and Postorder Traversal
func buildTree(inorder []int, postorder []int) *TreeNode {
if len(inorder) == 0{
return nil
}
node := new(TreeNode)
// 根节点为后序数组的最后一个元素
node.Val = postorder[len(postorder)-1]
// 求左右子树的分割线
index := 0
for k, v := range inorder{
if v == node.Val{
index = k
break
}
}
// 求左右子树的中序数组
lin, rin := inorder[:index], inorder[index+1:]
// 求左右子树的后序数组
lpost, rpost := postorder[:len(lin)], postorder[len(lin):len(rin)+len(lin)]
node.Left = buildTree(lin, lpost)
node.Right = buildTree(rin, rpost)
return node
}
617. Merge Two Binary Trees
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
if root1 == nil {
return root2
}
if root2 == nil {
return root1
}
root := new(TreeNode)
root.Val = root1.Val + root2.Val
root.Left = mergeTrees(root1.Left, root2.Left)
root.Right = mergeTrees(root1.Right, root2.Right)
return root
}
700. Search in a Binary Search Tree
func searchBST(root *TreeNode, val int) *TreeNode {
for root != nil{
if val > root.Val{
root = root.Right
}else if val < root.Val{
root = root.Left
}else{
break
}
}
return root
}
501. Find Mode in Binary Search Tree
// 中序遍历, 递归、迭代
// 与前一个节点值比较
// pre, node0, node1, node2, ...
func findMode(root *TreeNode) []int {
res, count, max := make([]int, 0), 1, 1
var pre *TreeNode
var rec func(*TreeNode)
rec = func(cur *TreeNode){
if cur == nil{
return
}
// 遍历左
rec(cur.Left)
// 对访问节点的处理
if pre != nil && cur.Val == pre.Val{
count++
}else{
count = 1
}
if count == max{
res = append(res, cur.Val)
}else if count > max{
max = count
res = []int{cur.Val}
}
pre = cur
// 遍历右
rec(cur.Right)
}
rec(root)
return res
}
235. Lowest Common Ancestor of a Binary Search Tree
// 递归
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil {
return nil
}
// p, q在左子树
if p.Val < root.Val && q.Val < root.Val{
return lowestCommonAncestor(root.Left, p, q)
}
// p, q在右子树
if p.Val > root.Val && q.Val > root.Val{
return lowestCommonAncestor(root.Right, p, q)
}
// p, q在两侧
return root
}
// 迭代法
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
for root != nil{
if p.Val < root.Val && q.Val < root.Val{
root = root.Left
}else if p.Val > root.Val && q.Val > root.Val{
root = root.Right
}else{
return root
}
}
return nil
}
701. Insert into a Binary Search Tree
func insertIntoBST(root *TreeNode, val int) *TreeNode {
if root == nil {
return &TreeNode{Val: val}
}
if val > root.Val {
root.Right = insertIntoBST(root.Right, val)
} else {
root.Left = insertIntoBST(root.Left, val)
}
return root
}
450. Delete Node in a BST
func deleteNode(root *TreeNode, key int) *TreeNode {
if root == nil{
return nil
}
if root.Val == key{
if root.Right == nil{
return root.Left
}
// 求右子树最小值节点
node := root.Right
for node.Left != nil{
node = node.Left
}
root.Val = node.Val
root.Right = deleteNode(root.Right, node.Val)
return root
}
root.Left = deleteNode(root.Left, key)
root.Right = deleteNode(root.Right, key)
return root
}
func deleteNode(root *TreeNode, key int) *TreeNode {
if root == nil{
return nil
}
if root.Val == key{
node := root.Right
if node == nil{
return root.Left
}
// 求右子树最小值节点
for node.Left != nil{
node = node.Left
}
root.Val, node.Val = node.Val, root.Val
}
root.Left = deleteNode(root.Left, key)
root.Right = deleteNode(root.Right, key)
return root
}
669. Trim a Binary Search Tree
// 递归
func trimBST(root *TreeNode, low int, high int) *TreeNode {
if root == nil{
return nil
}
if high < root.Val{
return trimBST(root.Left, low, high)
}
if low > root.Val{
return trimBST(root.Right, low, high)
}
root.Left = trimBST(root.Left, low, high)
root.Right = trimBST(root.Right, low, high)
return root
}
// 迭代
func trimBST(root *TreeNode, low int, high int) *TreeNode {
if root == nil{
return nil
}
for root != nil && (high < root.Val || low > root.Val) {
if root.Val > high{
root = root.Left
}else {
root = root.Right
}
}
cur := root
for cur != nil{
// 不断增大左节点的值
for cur.Left != nil && cur.Left.Val < low{
cur.Left = cur.Left.Right
}
cur = cur.Left
}
cur = root
for cur != nil{
for cur.Right != nil && cur.Right.Val > high{
cur.Right = cur.Right.Left
}
cur = cur.Right
}
return root
}
108. Convert Sorted Array to Binary Search Tree
// 递归
func sortedArrayToBST(nums []int) *TreeNode {
if len(nums) == 0{
return nil
}
root := new(TreeNode)
index := len(nums)/2
root.Val = nums[index]
root.Left = sortedArrayToBST(nums[:index])
root.Right = sortedArrayToBST(nums[index+1:]) // 这里不会下标越界
return root
}
// 迭代
// 中序遍历填充平衡树
func sortedArrayToBST(nums []int) *TreeNode {
root := getTree(len(nums))
stack := make([]*TreeNode, 0)
stack = append(stack, root)
k := 0
for len(stack) > 0{
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if node != nil{
if node.Right != nil {
stack = append(stack, node.Right)
}
stack = append(stack, node, nil)
if node.Left != nil {
stack = append(stack, node.Left)
}
}else{
stack[len(stack)-1].Val = nums[k]
stack = stack[:len(stack)-1]
k++
}
}
return root
}
// 层级遍历构建平衡树
func getTree(num int)*TreeNode{
root := new(TreeNode)
queue := make([]*TreeNode, 0)
queue = append(queue, root)
count := 1
for len(queue) > 0{
n := len(queue)
for i := 0; i < n; i++{
node := queue[0]
queue = queue[1:]
if count < num{
node.Left = new(TreeNode)
queue = append(queue, node.Left)
count++
}
if count < num{
node.Right = new(TreeNode)
queue = append(queue, node.Right)
count++
}
}
}
return root
}
538. Convert BST to Greater Tree
// 递归
func convertBST(root *TreeNode) *TreeNode {
var sum int
var rec func(*TreeNode)
rec = func(node *TreeNode){
if node == nil{
return
}
rec(node.Right)
sum += node.Val
node.Val = sum
rec(node.Left)
}
rec(root)
return root
}
// 迭代
func convertBST(root *TreeNode) *TreeNode {
stack := make([]*TreeNode, 0)
if root != nil{
stack = append(stack, root)
}
sum := 0
for len(stack) > 0{
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if node != nil{
if node.Left != nil {
stack = append(stack, node.Left)
}
stack = append(stack, node, nil)
if node.Right != nil {
stack = append(stack, node.Right)
}
}else{
node2 := stack[len(stack)-1]
sum += node2.Val
node2.Val = sum
stack = stack[:len(stack)-1]
}
}
return root
}
116. Populating Next Right Pointers in Each Node
func connect(root *Node) *Node {
if root == nil{
return nil
}
var rec func(*Node, *Node)
rec = func(l, r *Node){
if l == nil || r == nil{
return
}
l.Next = r
rec(l.Left, l.Right)
rec(r.Left, r.Right)
rec(l.Right, r.Left)
}
rec(root.Left, root.Right)
return root
}
Sort
Quick Sort
func sortArray(nums []int) []int {
var quickSort func(*[]int, int, int)
quickSort = func(nums *[]int, left, right int){
if right - left + 1 < 2{
return
}
p := part(nums, left, right)
quickSort(nums, left, p-1)
quickSort(nums, p+1, right)
}
quickSort(&nums, 0, len(nums)-1)
return nums
}
func part(numsPtr *[]int, left, right int)int{
nums := *numsPtr
v := nums[left]
for left < right{
for left < right && nums[right] >= v{
right--
}
nums[left] = nums[right]
for left < right && nums[left] <= v{
left++
}
nums[right] = nums[left]
}
nums[left] = v
return left
}
// 快排
func sortArray(nums []int) []int {
if len(nums) < 2{
return nums
}
p := part(nums)
sortArray(nums[:p])
sortArray(nums[p+1:])
return nums
}
func part(nums []int)int{
if len(nums) < 2{
return 0
}
v := nums[0]
left, right := 0, len(nums) - 1
for left < right{
for left < right && nums[right] >= v{
right--
}
nums[left] = nums[right]
for left < right && nums[left] <= v{
left++
}
nums[right] = nums[left]
}
nums[left] = v
return left
}
Merge Sort
func sortArray(nums []int) []int {
if len(nums) < 2{
return nums
}
mid := len(nums) / 2
nums1 := sortArray(nums[:mid])
nums2 := sortArray(nums[mid:])
nums = merge(nums1, nums2)
return nums
}
func merge(nums1, nums2 []int)[]int{
if len(nums1) == 0 {
return nums2
}else if len(nums2) == 0{
return nums1
}
res := make([]int, 0, len(nums1)+len(nums2))
i, j := 0, 0
for i < len(nums1) && j < len(nums2){
if nums1[i] < nums2[j]{
res = append(res, nums1[i])
i++
}else{
res = append(res, nums2[j])
j++
}
}
if i < len(nums1){
res = append(res, nums1[i:]...)
}else if j < len(nums2){
res = append(res, nums2[j:]...)
}
return res
}
Bubble Sort
// swap len(array) - 1 time
// swap len(array) - 2 time
// ...
// swap 1 time
func BubbleSort(array []int) []int {
for n := len(array) - 1; n >= 1; n-- {
for i := 0; i < n; i++ {
if array[i] > array[i+1] {
array[i], array[i+1] = array[i+1], array[i]
}
}
}
return array
}
Selection Sort
// select min of array[0:] and store at 0th index
// select min of array[1:] and store at 1th index
// ...
func SelectionSort(array []int) []int {
for i := 0; i < len(array)-1; i++ {
idxOfMin := i
for j := i; j < len(array); j++ {
if array[j] < array[idxOfMin] {
idxOfMin = j
}
}
array[i], array[idxOfMin] = array[idxOfMin], array[i]
}
return array
}
Insertion Sort
// array[0:i] sorted
// array[i:] unsorted
// insert ith num into sorted array[:i]
func InsertionSort(array []int) []int {
for i := 1; i < len(array); i++ {
for j := i - 1; j >= 0; j-- {
if array[j] > array[j+1] {
array[j], array[j+1] = array[j+1], array[j]
continue
}
break
}
}
return array
}
215. Kth Largest Element in an Array
func findKthLargest(nums []int, k int) int {
index := part(nums)
if index == len(nums) - k{
return nums[index]
}
if index < len(nums) - k{
return findKthLargest(nums[index+1:], k)
}
return findKthLargest(nums[:index], index - len(nums) + k)
}
func part(nums []int)int{
if len(nums) == 0{
return 0
}
left, right := 0, len(nums) - 1
v := nums[0]
for left < right{
for left < right && nums[right] >= v{
right--
}
nums[left] = nums[right]
for left < right && nums[left] <= v{
left++
}
nums[right] = nums[left]
}
nums[left] = v
return left
}
Back Tracking
77. Combinations
Input: n = 4, k = 2
Output:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
func combine(n int, k int) [][]int {
var res [][]int
var rec func(int, []int)
rec = func(start int, path []int){
if len(path) == k{
res = append(res, append(make([]int, 0, k), path...))
return
}
// 还需要 k-len(path) 个元素
// 最多还可以追加 n - i + 1 个元素
// n - i + 1 >= k - len(path)
// i <= n - k + len(path) + 1
for i := start; i <= n- k + len(path) + 1; i++{
path = append(path, i)
rec(i+1, path)
path = path[:len(path)-1]
}
}
rec(1, make([]int, 0, k))
return res
}
// 递归不传参数
func combine(n int, k int) [][]int {
var res [][]int
path := make([]int, 0, k)
var rec func(int)
rec = func(start int){
if len(path) == k{
res = append(res, append(make([]int, 0, k), path...))
return
}
for i := start; i <= n - k + len(path) + 1; i++{
path = append(path, i)
rec(i+1)
path = path[:len(path)-1]
}
}
rec(1)
return res
}
39. Combination Sum
Input: candidates = [2,3,5], target = 8
Output: [[2,2,2,2],[2,3,3],[3,5]]
func combinationSum(candidates []int, target int) [][]int {
var res [][]int
var path []int
var rec func(int)
rec = func(start int){
if target <= 0{
if target == 0{
res = append(res, append(make([]int, 0), path...))
}
return
}
for i := start; i < len(candidates); i++{
path = append(path, candidates[i])
target -= candidates[i]
rec(i)
path = path[:len(path)-1]
target += candidates[i]
}
}
rec(0)
return res
}
93. Restore IP Addresses
func restoreIpAddresses(str string) []string {
res := make([]string, 0)
var rec func(int, []string)
rec = func(start int, parts []string){
if len(parts) == 3{
part := str[start:]
if validIpPart(part){
parts = append(parts, part)
res = append(res, strings.Join(parts, "."))
}
return
}
for end := start+1; end <= start + 3 && end <= len(str); end++{
part := str[start:end]
if !validIpPart(part){
continue
}
parts = append(parts, part)
rec(end, parts)
parts = parts[:len(parts)-1]
}
}
rec(0, []string(nil))
return res
}
func validIpPart(str string) bool{
if len(str) == 0{
return false
}
if str[0:1] == "0" && str != "0"{
return false
}
if len(str) > 3{
return false
}
if len(str) == 3 && str > "255"{
return false
}
return true
}
// method 2
func restoreIpAddresses(s string) []string {
var res []string
k := 3 // 放入3个点
n := len(s) - 1 // 可放点的位置数量
var path []int
var rec func(int)
rec = func(start int){
if len(path) == k{
if ip, ok := isValidIP(s, path); ok{
res = append(res, ip)
}
return
}
// n - i + 1 = k - len(path)
for i := start; i <= n - k + len(path) + 1; i++{
path = append(path, i)
rec(i+1)
path = path[:len(path)-1]
}
}
rec(1)
return res
}
func isValidIP(s string, path []int)(string, bool){
segments := []string{
str[:indice[0]],
str[indice[0]:indice[1]],
str[indice[1]:indice[2]],
str[indice[2]:],
}
for _, v := range segments{
if !isValidSeg(v){
return "", false
}
}
return strings.Join(segments, "."), true
}
func isValidSeg(s string)bool{
if len(s) > 1 && s[0] == '0'{
return false
}
if len(s) > 3{
return false
}
if len(s) == 3 && s > "255"{
return false
}
return true
}
90. Subsets II
Input: nums = [1,2,2]
Output: [[],[1],[1,2],[1,2,2],[2],[2,2]]
func subsetsWithDup(nums []int) [][]int {
sort.Ints(nums) // 去重关键
var res [][]int
var path []int
var rec func(int)
rec = func(start int){
res = append(res, append(make([]int, 0), path...))
for i := start; i < len(nums); i++{
if i > start && nums[i] == nums[i-1]{ // 去重关键
continue
}
path = append(path, nums[i])
rec(i+1)
path = path[:len(path)-1]
}
}
rec(0)
return res
}
47. Permutations II
Input:
nums = [1,1,2]
Output:
[[1,1,2],
[1,2,1],
[2,1,1]]

func permuteUnique(nums []int) [][]int {
sort.Ints(nums) // 去重关键
var res [][]int
k := len(nums)
var rec func([]bool, []int)
rec = func(used []bool, path []int){
if len(path) == k{
res = append(res, append(make([]int, 0, k), path...))
return
}
for i := 0; i < k; i++{
// skip the used
if used[i] {
continue
}
// sift the unused and remove the duplicated
if i > 0 && !used[i-1] && nums[i] == nums[i-1]{
continue
}
used[i] = true // 加入到path了
path = append(path, nums[i])
rec(used, path)
used[i] = false
path = path[:len(path)-1]
}
}
rec(make([]bool, k), []int(nil))
return res
}
51. N-Queens
func solveNQueens(n int) [][]string {
res := make([][]string, 0)
var rec func([]bool, []int)
rec = func(used []bool, path []int){
if len(path) == n{
res = append(res, covert(path))
return
}
diagonallyUsed := diagonallyUsed(n, path)
for i := 0; i < n; i++{
// 跳过列的位置
if used[i]{
continue
}
// 跳过斜对角的位置
if diagonallyUsed[i]{
continue
}
used[i] = true
path = append(path, i)
rec(used, path)
used[i] = false
path = path[:len(path)-1]
}
}
rec(make([]bool, n), []int(nil))
return res
}
func covert(path []int)[]string{
res := make([]string, 0, len(path))
template := make([]string, 0, len(path))
for i := 0; i < len(path); i++{
template = append(template, ".")
}
for _, v := range path{
template[v] = "Q"
res = append(res, strings.Join(template, ""))
template[v] = "."
}
return res
}
func diagonallyUsed(n int, path []int)[]bool{
res := make([]bool, n)
for k, v := range path{
if i := v - (len(path) - k); i >= 0{
res[i] = true
}
if i := v + (len(path) - k); i <= n-1{
res[i] = true
}
}
return res
}
Greedy Algorithm
376. Wiggle Subsequence
func wiggleMaxLength(nums []int) int {
if len(nums) < 2{
return len(nums)
}
res := 1
preDiff := 0
for i := 0; i < len(nums) - 1; i++{
curDiff := nums[i+1] - nums[i]
if curDiff > 0 && preDiff <= 0 || curDiff < 0 && preDiff >= 0 {
res++
preDiff = curDiff
}
}
return res
}
53. Maximum Subarray
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
func maxSubArray(nums []int) int {
res := nums[0]
sum := 0
for i := 0; i < len(nums); i++{
sum += nums[i]
if sum > res{
res = sum
}
// 贪心
// sum < 0时不参与累加
if sum < 0{
sum = 0
}
}
return res
}
Dalymic Programing
188. Best Time to Buy and Sell Stock IV
// 最多买卖k次
func maxProfit(k int, prices []int) int {
k = min(k, len(prices) / 2)
buy := make([]int, k+1)
for i := range buy{
buy[i] = -1<<31
}
sell := make([]int, k+1)
for _, p := range prices{
for j := 1; j < k+1; j++{
buy[j] = max(buy[j], sell[j-1]-p)
sell[j] = max(sell[j], buy[j]+p)
}
}
return sell[len(sell)-1]
}
123. Best Time to Buy and Sell Stock III
// 限定2次
func maxProfit(prices []int) int {
buy1, sell1, buy2, sell2 := -1<<31, 0, -1<<31, 0
for _, p := range prices{
buy1 = max(buy1, 0 - p)
sell1 = max(sell1, buy1 + p)
buy2 = max(buy2, sell1 - p)
sell2 = max(sell2, buy2 + p)
}
return sell2
}
122. Best Time to Buy and Sell Stock II
// 不限次
func maxProfit(prices []int) int {
buy, sell := -1<<31, 0
for _, p := range prices{
buy = max(buy, sell - p)
sell = max(sell, buy + p)
}
return sell
}
func maxProfit(prices []int) int {
cache := make(map[int]int)
return rec(len(prices)-1, false, prices, cache)
}
func rec(i int, hold bool, prices []int, cache map[int]int)int{
key := getKey(i, hold)
if v, ok := cache[key]; ok{
return v
}
if i == 0{
if hold{
return -prices[0]
}else{
return 0
}
}
if hold{
cache[key] = max(rec(i-1, true, prices, cache),
rec(i-1, false, prices, cache) - prices[i])
return cache[key]
}
cache[key] = max(rec(i-1, false, prices, cache),
rec(i-1, true, prices, cache) + prices[i])
return cache[key]
}
func getKey(i int, hold bool)int{
if hold{
return i
}
return -i
}
309. Best Time to Buy and Sell Stock with Cooldown
// 不限次+冷冻期
func maxProfit(prices []int) int {
buy, preSell, sell := -1<<31, 0, 0
for _, p := range prices{
buy = max(buy, preSell - p) // buy基于上上一次sell
sell, preSell = max(sell, buy + p), sell
}
return sell
}
714. Best Time to Buy and Sell Stock with Transaction Fee
// 不限次+手续费
func maxProfit(prices []int, fee int) int {
buy, sell := -1<<31, 0
for _, p := range prices{
buy = max(buy, sell - p - fee)
sell = max(sell, buy + p)
// 或者
// buy = max(buy, sell - p)
// sell = max(sell, buy + p -fee)
}
return sell
}
func max(a, b int)int{
if a > b {
return a
}
return b
}
416. Partition Equal Subset Sum
// 01背包
// n 商品数量,w 商品体积,v 商品价值, c 背包容量
// 第i个商品选或者不选
// rec(i, c) = max(rec(i-1, c), rec(i-1, c-w[i]) + v[i])
func canPartition(nums []int) bool {
target := 0
for _, v := range nums{
target += v
}
if target % 2 != 0{
return false
}
target /= 2
cache := make(map[string]bool)
var rec func(int, int)bool
rec = func(i, c int)bool{
if i < 0{
if c == 0{
return true
}
return false
}
k := getKey(i, c)
if _, ok := cache[k]; ok{
return cache[k]
}
if c < nums[i]{
cache[k] = rec(i-1, c)
return cache[k]
}
cache[k] = rec(i-1, c) || rec(i-1, c-nums[i])
return cache[k]
}
return rec(len(nums)-1, target)
}
func getKey(i, c int)string{
return string([]rune{rune(i), rune(c)})
}
518. Coin Change 2
// 完全背包
// n 商品数量,w 商品体积,v 商品价值, c 背包容量
// 第i个商品选或者不选且可以重复选
// rec(i, c) = max(rec(i-1, c), rec(i, c-w[i]) + v[i])
func change(amount int, coins []int) int {
cache := make(map[string]int)
var rec func(int, int)int
rec = func(i, c int)int{
if i < 0{
if c == 0{
return 1
}
return 0
}
k := getKey(i, c)
if _, ok := cache[k]; ok{
return cache[k]
}
if c < coins[i]{
cache[k] = rec(i-1, c)
return cache[k]
}
cache[k] = rec(i-1, c) + rec(i, c-coins[i])
return cache[k]
}
return rec(len(coins)-1, amount)
}
func getKey(i, c int)string{
return string([]rune{rune(i), rune(c)})
}
func change(amount int, coins []int) int {
n := len(coins) // 商品总数
dp := make([]int, amount+1)
dp[0] = 1
for i := 0; i < n; i++{
for j := coins[i]; j <= amount; j++{
dp[j] = dp[j] + dp[j-coins[i]]
}
}
return dp[amount]
}
1049. Last Stone Weight II
func lastStoneWeightII(stones []int) int {
sum := 0
for _, v := range stones{
sum += v
}
target := sum/2
n := len(stones)
dp := make([]int, target+1)
for i := 1; i <= n; i++{
for j := target; j >= stones[i-1]; j--{
dp[j] = max(dp[j], dp[j-stones[i-1]] + stones[i-1])
}
}
return sum - 2*dp[target]
}
func max(a, b int)int{
if a > b{
return a
}
return b
}
494. Target Sum
Input: nums = [1,1,1,1,1], target = 3
Output: 5
Explanation: There are 5 ways to assign symbols to make the sum of nums be target 3.
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3
// 回溯
func findTargetSumWays(nums []int, target int) int {
res, total := 0, 0
for _, v := range nums{
total += v
}
var rec func(int, int)
rec = func(start, sum int){
if sum - (total - sum) == target{
res++
}
for i := start; i < len(nums); i++{
sum += nums[i]
rec(i+1, sum)
sum -= nums[i]
}
}
rec(0, 0)
return res
}
// dp
func findTargetSumWays(nums []int, target int) int {
total := 0
for _, v := range nums{
total += v
}
// x - (total - x) = target
// x = (target + total) / 2
if (total + target) % 2 != 0{
return 0
}
target = (target + total) / 2
capicity := target
if target < 0{
capicity = -target
}
// dp[j] 表示刚好填满容量j的途径的数量
dp := make([]int, capicity+1)
dp[0] = 1
for i := 1; i <= len(nums); i++{
for j := target; j >= nums[i-1]; j--{
dp[j] = dp[j] + dp[j-nums[i-1]]
}
}
return dp[capicity]
}
300. Longest Increasing Subsequence
Input: nums = [10,9,2,5,3,7,101,18]
Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
// O(nlogn)
// sort.SearchInts(s, v) 返回v在有序数组s中的下标,如果与元素相等,则排在元素前面
func lengthOfLIS(nums []int) int {
var s []int
for _, v := range nums{
i := sort.SearchInts(s, v)
if i == len(s){
s = append(s, v)
}else{
s[i] = v
}
}
return len(s)
}
// dp
func lengthOfLIS(nums []int) int {
if len(nums) <= 1{
return len(nums)
}
res := 0
// dp[i]表示以nums[i]为结尾的LIS,所以dp[i] >= 1
dp := make([]int, len(nums))
for i := range dp{
dp[i] = 1
}
for i := 1; i < len(nums); i++{
for j := 0; j < i; j++{
if nums[i] > nums[j]{
dp[i] = max(dp[i], dp[j]+1)
}
}
res = max(res, dp[i])
}
return res
}
func max(a, b int)int{
if a > b{
return a
}
return b
}
718. Maximum Length of Repeated Subarray
Input: nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
Output: 3
Explanation: The repeated subarray with maximum length is [3,2,1].

func findLength(nums1 []int, nums2 []int) int {
res := 0
dp := make([][]int, len(nums1)+1)
for i := range dp{
dp[i] = make([]int, len(nums2)+1)
}
for i, v1 := range nums1{
for j, v2 := range nums2{
if v1 == v2{
dp[i+1][j+1] = dp[i][j] + 1
}
if dp[i+1][j+1] > res{
res = dp[i+1][j+1]
}
}
}
return res
}
func findLength(nums1 []int, nums2 []int) int {
res := 0
dp := make([]int, len(nums2)+1)
for i := 0; i < len(nums1); i++{
for j := len(nums2) - 1; j >= 0; j--{ // dp[j+1]依赖前面的元素,必须从大到小遍历
if nums1[i] == nums2[j]{
dp[j+1] = dp[j] + 1
}else{
dp[j+1] = 0
}
if dp[j+1] > res{
res = dp[j+1]
}
}
}
return res
}
1143. Longest Common Subsequence
Input: text1 = “abcde”, text2 = “ace”
Output: 3
func longestCommonSubsequence(text1 string, text2 string) int {
dp := make([][]int, len(text1)+1)
for i := range dp{
dp[i] = make([]int, len(text2)+1)
}
for i, v1 := range text1{
for j, v2 := range text2{
if v1 == v2{
dp[i+1][j+1] = dp[i][j] + 1
}else{
dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j])
}
}
}
return dp[len(text1)][len(text2)]
}
func max(a, b int)int{
if a > b{
return a
}
return b
}
1035. Uncrossed Lines
Input: nums1 = [1,4,2], nums2 = [1,2,4]
Output: 2
解法同 1143. Longest Common Subsequence
#
53. Maximum Subarray
Input: nums = [3,5,-9,1,3,-2,3,4,7,2,-9,6,3,1,-5,4]
Output: 19
Explanation: [1,3,-2,3,47,2,-9,6,3,1] has the largest sum = 19.
func maxSubArray(nums []int) int {
res := nums[0]
dp := make([]int, len(nums))
dp[0] = nums[0] // max subarray ends with nums[0]
for i := 1; i < len(nums); i++{
if dp[i-1] > 0{
dp[i] = dp[i-1] + nums[i] // max subarray ends with nums[i]
}else{
dp[i] = nums[i]
}
if dp[i] > res{
res = dp[i]
}
}
return res
}
115. Distinct Subsequences
Input: s = “rabbbit”, t = “rabbit”
Output: 3
Explanation:
As shown below, there are 3 ways you can generate “rabbit” from s.
rabbbit
rabbbit
rabbbit
// dp
func numDistinct(s string, t string) int {
dp := make([][]int, len(s)+1)
for i := range dp{
dp[i] = make([]int, len(t)+1)
dp[i][0] = 1
}
for i, v1 := range s{
for j, v2 := range t{
if v1 == v2{
dp[i+1][j+1] = dp[i][j] + dp[i][j+1]
}else{
dp[i+1][j+1] = dp[i][j+1]
}
}
}
return dp[len(s)][len(t)]
}
// 递归
func numDistinct(s string, t string) int {
dp := make([][]int, len(s)+1)
for i := range dp{
dp[i] = make([]int, len(t)+1)
for j := range dp[i]{
dp[i][j] = -1
}
}
var rec func(int, int)int
rec = func(i, j int)int{
if j < 0{
return 1
}
if i < 0{
return 0
}
if s[i] == t[j]{
// return rec(i-1, j-1) + rec(i-1, j)
if dp[i][j] == -1{
dp[i][j] = rec(i-1, j-1)
}
if dp[i][j+1] == -1{
dp[i][j+1] = rec(i-1, j)
}
return dp[i][j] + dp[i][j+1]
}else{
// return rec(i-1, j)
if dp[i][j+1] == -1{
dp[i][j+1] = rec(i-1, j)
}
return dp[i][j+1]
}
}
return rec(len(s)-1, len(t)-1)
}