当前位置:网站首页>二分查找处理不当引起的堆栈溢出异常
二分查找处理不当引起的堆栈溢出异常
2022-08-05 12:59:00 【小刘学安卓】
在刷题的时候,使用了二分查找找出目标数在升序数组的位置,但是一运行发现报错提示堆栈异常,即不断地递归,而没有走到递归出口逻辑。
一、算法题:和为S的两个数字
输入一个升序数组 array 和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,返回任意一组即可,如果无法找出这样的数字,返回一个空数组即可。
数据范围: 0 < len(array) <10^5 , 1 < array[i] < 10^6

我想到的解题思路是先通过二分查找,找出目标数在数组中最应该出现的位置,然后再找出子数组中满足条件的两个数。所以使用到了二分查找。代码如下:
import java.util.*;
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
//先用二分查找找出sum在升序数组中,保证插入后依然有序的情况下,应该插入的位置
//然后从左边的子数组中寻找符合条件的两个数
ArrayList<Integer> targetList = new ArrayList<>();
int targetIndex = binarySearch(array, sum + 0.5, 0, array.length - 1);
int head = 0; //头指针
int tail = targetIndex; //尾指针
while (head < tail) {
if (array[head] + array[tail] == sum) {
targetList.add(array[head]);
targetList.add(array[tail]);
break;
} else if (array[head] + array[tail] > sum) {
tail--;
} else {
head++;
}
}
return targetList;
}
//二分查找找出最靠近double类型sum值的下标为止
public int binarySearch(int [] array, double sum, int start, int end) {
if (start >= end) return start;
int mid = (start + end) / 2;
if (array[mid] > sum) {
end = mid;
} else {
start = mid;
}
return binarySearch(array, sum, start, end);
}
}一运行就报错如下:
请检查是否存在数组越界等非法访问情况
Exception in thread "main" java.lang.StackOverflowError
at Solution.binarySearch(Solution.java:34)
at Solution.binarySearch(Solution.java:34)
at Solution.binarySearch(Solution.java:34)
at Solution.binarySearch(Solution.java:34)
at Solution.binarySearch(Solution.java:34)
at Solution.binarySearch(Solution.java:34)
at Solution.binarySearch(Solution.java:34)输入的测试数据为:array=[1,4,9], sum=8
二、异常原因分析
//二分查找找出最靠近double类型sum值的下标为止
public int binarySearch(int [] array, double sum, int start, int end) {
if (start >= end) return start;
int mid = (start + end) / 2;
if (array[mid] > sum) {
end = mid;
} else {
start = mid;
}
return binarySearch(array, sum, start, end);
}问题出在二分查找实现上,对start和end动态调整是错误的。
就拿array=[1,4,9]数组来分析
1、参数:sum=8.5, start=0, end=2;
2、进入函数内部逻辑, 不满足start >= end,所以接着求mid=(0 + 2)/ 2 = 1。array[1]=4<8.5,所以end=mid=1; 接着使用新参数调用了函数本身;
3、参数:sum=8.5, start=1, end=2;
4、进入函数内部逻辑, 不满足start >= end,所以接着求mid=(1 + 2)/ 2 = 1。array[1]=4<8.5,所以end=mid=1; 接着使用新参数调用了函数本身;
5、参数:sum=8.5, start=1, end=2;
6、这时就发现,程序进入死循环了!!!
如你所看到的,计算出的start=1, end=2,其mid=1,如果函数中不对mid进行+1或-1,则mid永远不变。start永远不会有大于等于end的情况。
要想能走到递归函数的出口,则在处理mid的时候就必须对mid进行左移-1或右移+1。
所以,在对start和end动态调整的时候,不能把mid直接赋值给它们,而是必须下面这样:
//二分查找找出最靠近double类型sum值的下标为止
public int binarySearch(int [] array, double sum, int start, int end) {
if (start >= end) return start;
int mid = (start + end) / 2;
if (array[mid] > sum) {
end = mid - 1;
} else {
start = mid + 1;
}
return binarySearch(array, sum, start, end);
}接着运行程序,通过了!
边栏推荐
- The memory problem is difficult to locate, that's because you don't use ASAN
- C进阶-自定义类型:结构体,枚举,联合
- 通俗易懂玩QT:QT程序发布打包
- 使用ModelArts实现AnimeGANv2照片动漫化
- 买个社区团购小程序多少钱呢?微信社区团购小程序怎么做
- RT-Thread recording (2. RT-Thread kernel startup process - startup file and source code analysis)
- 《MySQL核心知识》第3章:MySQL中的运算符
- ansible-playbook使用普通用户提权
- 内存问题难定位,那是因为你没用ASAN
- How does the bank transaction system ensure strong consistency of data transactions?Via the database component?How to ensure the normal consistency of database transaction data under high concurrency?
猜你喜欢
随机推荐
奇思妙想构造题 ARC145 D - Non Arithmetic Progression Set
到底怎么个DAO
Small HCIP - BGP comprehensive experiment
ApiPost使用教程
一致性协议-ChainPaxos详解
配置了feign.hystrix.enabled:=true不生效的原因
115. In-depth explanation of the technical implementation of configuring the local SAP UI5 application to the local Fiori Launchpad
Kuaike Electronics is listed on Shenzhen Stock Exchange: market value of 8.2 billion, annual revenue of 700 million and fundraising of 560 million
ipv4: inet初始化过程
MySQL约束之check
可编程直流电源是一种稳定可靠的电源设备
《MySQL核心知识》第1章:开篇:专栏介绍
Under the heavy pressure of the epidemic, why is Watsons still profitable in the first half of the year?
115. 关于将本地 SAP UI5 应用配置到本地 Fiori Launchpad 的技术实现深入讲解
A brief explanation of permutation and combination
NFT卡牌游戏系统dapp开发NFT链游技术
The road to the rise of TypeScript brings us the valley selection ideas
Matplotlib 使用指南
js实现随机验证码(带干扰线)
MYSQL query duplicate data









