总结


小技巧

计算中间值(防止溢出)

mid = low + (high - low) / 2

向上取整
10 / 5 = 2
12 / 5 = 3

res = (a - 1)/b + 1

dfs

适用于路径探索。
使用vis数组的条件是,存在不同路径汇聚的情况,避免一个节点被访问多次。
在调用dfs函数之前,重置路径,路径上加入起点。

bfs

适用于连通性测试。
代码模板(包含四个变量)

func bfs() {
     // 首节点设置成已访问
    var vis [110]bool
    vis[1] = true
    
     // 首节点入队列
    var que [110]int
    que[0] = 1
    
    // 设置开始的下标和队列元素数量
    beginIndex := 0
    beginCount := 1
    
    // 只要队列还有元素就一直迭代
    for beginCount > 0 {
        // 新添加的元素数量入队列的开始下标
        nextIndex := beginIndex + beginCount
        // 新添加的元素数量,即下一层元素数量 
        nextCount := 0
        
        for i := 0; i < beginCount; i++ {
            index := que[i + beginIndex]
            ...
            if childCount == 0 {
    			...
            } else {
                for j := 0; j < childCount; j++ {
                    next := childList[index][j]

                    if !vis[next] {
                        vis[next] = true
                        // 新元素入队列
                        que[nextIndex] = next
                        nextIndex++
                        nextCount++
                    }
                }
            }
        }
        
         // 更新队列元素数量和开始的下标
        beginIndex += beginCount
        beginCount = nextCount
    }
}

二分查找

函数binarySearch表示传统的二分查找,没有找到时返回-1。
函数lowerBound表示寻找第一个值>=目标值对应的下标,没有找到时返回长度。
函数upperBound表示寻找第一个值>目标值对应的下标,没有找到时返回长度。

package main

import "fmt"

func binarySearch(nums []int, goal int) int {
   low := 0
   high := len(nums) - 1

   for low <= high {
      mid := low + (high - low) / 2
      if nums[mid] == goal {
         return mid
      } else if nums[mid] > goal {
         high = mid - 1
      } else {
         low = mid + 1
      }
   }

   return -1
}

func lowerBound(nums []int, goal int) int {
   low := 0
   high := len(nums)

   for low < high {
      mid := low + (high - low) / 2
      if nums[mid] >= goal {
         high = mid
      } else {
         low = mid + 1
      }
   }

   return high
}

func upperBound(nums []int, goal int) int {
   low := 0
   high := len(nums)

   for low < high {
      mid := low + (high - low) / 2
      if nums[mid] > goal {
         high = mid
      } else {
         low = mid + 1
      }
   }

   return high
}

func main() {
   nums := []int{1, 3, 5, 7, 8, 9}
   fmt.Println(binarySearch(nums, 8)) // 4
   fmt.Println(lowerBound(nums, 1))   // 0
   fmt.Println(upperBound(nums, 6))   // 3
}