func searchMatrix(matrix [][]int, target int) bool {
m := len(matrix)
if m == 0 {
return false
}
n := len(matrix[0])
index := sort.Search(m*n, func(i int) bool {
return matrix[i/n][i%n] >= target
})
return index < m*n && matrix[index/n][index%n] == target
}
Go 语言 sort.Search
使用解析:matrix[i/n][i%n] >= target
与 matrix[i/n][i%n] == target
的区别
index := sort.Search(m*n, func(i int) bool {
return matrix[i/n][i%n] >= target
})
index := sort.Search(m*n, func(i int) bool {
return matrix[i/n][i%n] >= target
})
在使用 sort.Search
进行二分查找时,我们经常需要定义一个单调递增的判断条件。本文将详细分析 matrix[i/n][i%n] >= target
和 matrix[i/n][i%n] == target
在 sort.Search
中的不同作用,并解释为什么前者更适合作为查找条件。
sort.Search
函数的工作原理
sort.Search(n, func(i int) bool { ... })
用于在 [0, n)
范围内查找第一个使 func(i) == true
的索引 i
。
-
如果找到符合条件的索引
i
,返回i
; -
如果所有元素都不满足
func(i) == true
,则返回n
。
sort.Search
要求 func(i int) bool
满足单调性(前半部分 false
,后半部分 true
),否则查找结果可能不准确。
matrix[i/n][i%n] == target
的问题
在 sort.Search
的回调函数中,如果直接使用 matrix[i/n][i%n] == target
,可能会导致 二分查找不符合单调性,进而导致错误。
示例:
matrix := [][]int{
{1, 3, 5},
{7, 9, 11},
}
target := 3
index := sort.Search(6, func(i int) bool {
return matrix[i/3][i%3] == target
})
fmt.Println(index) // 可能会返回错误的索引
问题点:
-
sort.Search
依赖于 单调递增的func(i) == true
判断逻辑。 -
matrix[i/n][i%n] == target
可能会导致true
断断续续出现,而不是单调递增。 -
sort.Search
可能跳过正确的target
,甚至导致数组访问越界(out of range
)。
matrix[i/n][i%n] >= target
的正确性
正确的 func(i int) bool
逻辑应保证前 false
后 true
,这意味着:
-
当
matrix[i/n][i%n] < target
时,返回false
-
当
matrix[i/n][i%n] >= target
时,返回true
正确示例:
import (
"fmt"
"sort"
)
func searchMatrix(matrix [][]int, target int) bool {
m, n := len(matrix), len(matrix[0])
index := sort.Search(m*n, func(i int) bool {
return matrix[i/n][i%n] >= target // 关键改动
})
return index != m*n && matrix[index/n][index%n] == target
}
func main() {
matrix := [][]int{
{1, 3, 5, 7},
{10, 11, 16, 20},
{23, 30, 34, 60},
}
target := 3
fmt.Println(searchMatrix(matrix, target)) // 输出: true
}
为什么 >= target
更合适?
-
保证单调性:
-
matrix[i/n][i%n] < target
时false
-
matrix[i/n][i%n] >= target
时true
-
-
确保找到第一个大于等于
target
的索引。 -
不会跳过
target
,同时避免out of range
访问。
结论
在使用 sort.Search
进行二分查找时,应使用 matrix[i/n][i%n] >= target
作为条件,而不是 matrix[i/n][i%n] == target
,这样可以确保单调性,避免索引越界,并保证查找结果正确。