Java实现的二分查找在元素存在时仍返回-1的问题求助
Java实现的二分查找在元素存在时仍返回-1的问题求助
嗨,我来帮你排查这个二分查找的问题~你的代码核心问题是二分查找的区间定义和边界处理不统一,这种混用会导致部分元素被错误判定为不存在(甚至你测试的5,按你贴的代码逻辑本应直接返回2,可能你实际运行的代码有笔误?不过这个写法确实存在明确的逻辑漏洞)。
先给你拆解问题所在:
二分查找通常有两种标准写法,核心原则是要保持「区间定义」和「循环条件、边界更新」的一致性,绝对不能混用:
1. 你的代码的矛盾点
你初始把right设为arr.length,这是左闭右开区间的写法(即查找范围是[left, right),包含left对应的元素,不包含right对应的位置),但后面处理arr[mid] > target时,却用了right = mid - 1——这是左闭右闭区间的处理逻辑(查找范围是[left, right],左右边界的元素都包含)。这种混搭会导致区间收缩错误,比如查找元素3时,你的代码会直接返回-1,即使它明明在数组里。
2. 两种正确的修正方案
方案一:坚持左闭右开区间写法
这种写法逻辑更简洁,不用处理边界相等的特殊情况:
public int binarySearch(int[] arr, int target) { int left = 0, right = arr.length; // 左闭右开区间,left < right时仍有未检查的元素 while (left < right) { // 用left + (right - left)/2替代(left+right)/2,避免整数溢出 int mid = left + (right - left) / 2; if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { // 目标在右半区,左边界移到mid+1(mid已确认不是目标) left = mid + 1; } else { // 目标在左半区,右边界设为mid(右开区间不包含mid,无需减1) right = mid; } } return -1; }
方案二:改用左闭右闭区间写法
这是更直观的写法,适合新手理解:
public int binarySearch(int[] arr, int target) { // 初始右边界设为最后一个元素的索引,对应左闭右闭区间[left, right] int left = 0, right = arr.length - 1; // 只要left <= right,就还有未检查的元素(包括left=right的单元素情况) while (left <= right) { int mid = left + (right - left) / 2; if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { // 目标在右半区,左边界移到mid+1(mid已排除) left = mid + 1; } else { // 目标在左半区,右边界移到mid-1(mid已排除) right = mid - 1; } } return -1; }
3. 额外小提示
用left + (right - left)/2计算mid比直接(left+right)/2更安全,因为当left和right都是很大的整数时,left+right可能会超出int的范围导致溢出。
你可以试试上面的修正代码,不管是找5还是其他元素,都能正确返回对应索引啦~
内容来源于stack exchange
相关产品推荐
相关产品推荐

