Week 11 @ 2025 算法周记【二分搜索】

二分搜索

LC 240. Search a 2D Matrix II 搜索二维矩阵 II

https://leetcode.com/problems/search-a-2d-matrix-ii/

(不是二分)

func searchMatrix(matrix [][]int, target int) bool { m, n := len(matrix), len(matrix[0]) i, j := 0, n-1 for i < m && j >= 0 { v := matrix[i][j] if v == target { return true } if v < target { i++ } else { j-- } } return false }

LC 392. Is Subsequence 判断子序列

https://leetcode.com/problems/is-subsequence/description/

(不是二分)

func isSubsequence(s string, t string) bool { if s == "" { return true } j := 0 for i := 0; i < len(t); i++ { if t[i] == s[j] { j++ if j == len(s) { return true } } } return false }

LC 792. Number of Matching Subsequences 匹配子序列的单词数

https://leetcode.com/problems/number-of-matching-subsequences/description/

暴力(没有超时)

func numMatchingSubseq(s string, words []string) int { count := 0 for _, word := range words { if isSubsequence(word, s) { count++ } } return count } func isSubsequence(s string, t string) bool { if s == "" { return true } j := 0 for i := 0; i < len(t); i++ { if t[i] == s[j] { j++ if j == len(s) { return true } } } return false }

预处理 + 二分

func numMatchingSubseq(s string, words []string) int { chars := getCharIndexes(s) count := 0 for _, word := range words { if isSubsequence(chars, word) { count++ } } return count } func getCharIndexes(s string) [][]int { result := make([][]int, 26) for i := range s { idx := charToIdx(s[i]) result[idx] = append(result[idx], i) } return result } func charToIdx(c byte) int { return int(c - 'a') } func isSubsequence(s [][]int, word string) bool { j := -1 for i := 0; i < len(word); i++ { j = search(s[charToIdx(word[i])], j) if j == -1 { return false } } return true } func search(arr []int, prevIndex int) int { target := prevIndex + 1 L, R := 0, len(arr)-1 for L < R { mid := L + (R - L) / 2 if arr[mid] >= target { R = mid } else { L = mid + 1 } } if R < 0 || R >= len(arr) { return -1 } if arr[R] <= prevIndex { return -1 } return arr[R] }

LC 658. 找到 K 个最接近的元素

https://leetcode.com/problems/find-k-closest-elements/description/

func findClosestElements(arr []int, k int, x int) []int { ii := leftBound(arr, x) if ii == len(arr) { return arr[len(arr)-k:len(arr)] } result := make([]int, 0, k) i, j := ii-1, ii // a < b for len(result) < k { if i < 0 { result = append(result, arr[j:j+k-len(result)]...) break } if j >= len(arr) { result = append(result, arr[i+1-k+len(result):i+1]..., ) break } if x-arr[i] <= arr[j]-x { result = append(result, arr[i]) i-- } else { result = append(result, arr[j]) j++ } } sort.Ints(result) return result } func leftBound(arr []int, x int) int { L, R := 0, len(arr) for L < R { mid := L + (R - L) / 2 if arr[mid] >= x { R = mid } else { L = mid + 1 } } return R }

LC 35. Search Insert Position 搜索插入位置

https://leetcode.com/problems/search-insert-position/description/

func searchInsert(nums []int, target int) int { L, R := 0, len(nums) for L < R { mid := L + (R - L) / 2 if nums[mid] >= target { R = mid } else { L = mid + 1 } } return R }

LC 162. Find Peak Element 寻找峰值

https://leetcode.com/problems/find-peak-element/description/

func findPeakElement(nums []int) int { L, R := 0, len(nums) for L < R { mid := L + (R -L) / 2 if mid == len(nums)-1 || nums[mid] > nums[mid + 1] { R = mid } else { L = mid + 1 } } return R }