package learn;
import java.util.Arrays;
/*二分法练习:在有序数组中查找目标值的索引。给定一个升序排序的整数数组numbers ,和一个目标值 target。在数组中找到目标值 target 的起始位置和结束位置
例如:int target = 5; 返回值:[0]
int target = 9; 返回值:[5,7]*/
public class BS {
//设置数组和目标值
static int[] numbers = {7, 7, 9, 9, 10, 11};
static int target = 7;
public static void main(String[] args)
{
//调用二分法,输入要查找的target和数组numbers,返回索引值
int[] result = search(target, numbers);
//打印结果
System.out.println(Arrays.toString(result));
}
//二分法查找方法
public static int[] search (int target, int[] numbers)
{
//检查数组是否为空数组
if (numbers == null || numbers.length == 0)
{
throw new IllegalArgumentException("数组为空");
}
//设置查找的起始和结束索引值start、end,成功找到的索引值TargetIndex
int start = 0;
int end = numbers.length - 1;
int TargetIndex = -1; //默认0,更改为-1方便条件判断
do
{
int mid = (start + end) / 2;
if (target == numbers[mid]) //如果目标数等于目前的中间数,找到,更新为目前索引值
{
TargetIndex = mid;
break;
}
else if (target > numbers[mid]) //如果目标数大于目前的中间数,将start更新为中间数,之后搜右半边
{
start = mid + 1;
}
else if (target < numbers[mid]) //如果目标数小于目前的中间数,将end更新为中间数,之后搜左半边
{
end = mid - 1;
}
} while (TargetIndex == -1 && start <= end);
//由于之前有star + 1和end - 1,所以当查找不到的时候会产生start > end的情况,可以通过这个来判断target不在数组中,防止while死循环的出现
//如果已经获得目标数的索引,下面要确认在该索引左、右还有多少个一样的目标数。
if (TargetIndex != -1)
{
//首先从TargetIndex向左遍历
for(int i = TargetIndex; i >= 0 && numbers[i] == target; i--)//这里i >= 0的判断一定要写在前面,不然i是超出索引值的直接就报错了,就这个bug半天都没发现
{
start = i;
}
//然后从TargetIndex向右遍历
for(int i = TargetIndex; i <= numbers.length - 1 && numbers[i] == target; i++)
{
end = i;
}
return new int[]{start, end};
}
else
{
System.out.println("目标值不在数组中");
return new int[]{-1, -1};
}
}
}
总结:
1.写之前觉得很简单都懂,但是真的从0开始写的时候还是花很多时间盘逻辑以及做限制
2.for循环条件判断有index值异常这个bug的时候本来想着问题不大随便改改,结果没认真改把自己越改越迷糊,不大的问题浪费了好多时间=.=
3.for语句里的and条件判断是按顺序判断的,只要前一个不符合了直接跳出,这题就是没注意这个导致了numbers[i]报错,i超出了index范围。