Go语言二分查找实现问题排查:为何该代码运行异常?
Go语言二分查找代码错误分析
核心错误:递归返回局部索引而非全局索引
你的代码在递归调用时,返回的是子数组的局部索引,而非原数组的全局索引,这会导致查找结果错误。以输入([]int{-1, 0, 3, 5, 9, 12}, 9)为例,执行流程如下:
- 初始调用:
nums = [-1,0,3,5,9,12],长度为6,mid=3,nums[mid]=5 < 9,递归调用Search(nums[4:],9)(子数组为[9,12])。 - 第二次调用:子数组长度为2,
mid=1,nums[mid]=12 >9,递归调用Search(nums[:1],9)(子数组为[9])。 - 第三次调用:子数组长度为1,
mid=0,nums[mid]=9,返回局部索引0。但这个0是子数组[9]的索引,对应原数组的索引应为4,最终返回结果错误。
次要问题:边界条件处理不当
代码中先计算mid再判断数组长度,若传入空数组,nums[mid]会直接触发数组越界panic。正确的逻辑应该先判断数组是否为空,再进行后续操作。
修复方案
方案1:递归传递偏移量
通过辅助函数传递当前子数组在原数组中的偏移量,计算全局索引:
func Search(nums []int, target int) int { return searchHelper(nums, target, 0) } func searchHelper(nums []int, target int, offset int) int { if len(nums) == 0 { return -1 } mid := len(nums) / 2 if nums[mid] == target { return mid + offset } if nums[mid] < target { return searchHelper(nums[mid+1:], target, offset + mid + 1) } return searchHelper(nums[:mid], target, offset) }
方案2:迭代实现二分查找
迭代方式更直观,直接操作原数组的左右边界,避免索引偏移问题:
func Search(nums []int, target int) int { left, right := 0, len(nums)-1 for left <= right { mid := left + (right-left)/2 // 防止整数溢出 if nums[mid] == target { return mid } else if nums[mid] < target { left = mid + 1 } else { right = mid - 1 } } return -1 }
内容的提问来源于stack exchange,提问作者lily
相关产品推荐
相关产品推荐

