一、需求
给你一个按照非递减顺序排列的整数数组 nums
,和一个目标值 target
。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target
,返回 [-1, -1]
。
注意:要求程序的时间复杂度是O(log2n)
具体功能点的要求如下:
数组:nums = [5, 7, 7, 8, 8, 10], target = 8 得到结果是:[3,4]
数组:nums = [5, 7, 7, 8, 8, 10], target = 6 得到结果是:[-1,-1]
数组:nums = [], target = 0 得到结果是:[-1,-1]
请设计一个方法完成以上需求,并编写测试代码完成上述测试。
二、算法分析
要求时间复杂度是O(log2n),所以不能使用循环遍历O(n),所以二分查找算法合适。
可以分两步,先找到左边最开始的索引,再找右边结束的索引。
三、算法代码
public class Test {
public static void main(String[] args) {
int[] nums = {5, 7, 7, 7, 7, 8, 8, 10};
int target;
Scanner sc = new Scanner(System.in);
System.out.println("请输入目标值:");
target = sc.nextInt();
int leftIndex = getLeftIndex(nums, target);
int rightIndex = getRightIndex(nums, target);
System.out.println("[" + leftIndex + ", " + rightIndex + "]");
}
private static int getLeftIndex(int[] nums, int target) {
// 二分查找该数据的位置
int start = 0;
int end = nums.length - 1;
int rs = -1; // 默认设置数据不存在
while (start <= end){
int middle = (start + end) / 2;
if (target > nums[middle]){
start = middle + 1;
}else if (target < nums[middle]){
end = middle - 1;
}else{
rs = middle;
// 继续二分查找往左边再找找看
end = middle - 1;
}
}
return rs;
}
private static int getRightIndex(int[] nums, int target) {
// 二分查找该数据的位置
int start = 0;
int end = nums.length - 1;
int rs = -1; // 默认设置数据不存在
while (start <= end){
int middle = (start + end) / 2;
if (target > nums[middle]){
start = middle + 1;
}else if (target < nums[middle]){
end = middle - 1;
}else{
rs = middle;
// 继续二分查找往左边再找找看
start = middle + 1;
}
}
return rs;
}
}
getLeftIndex 和 getRightIndex 代码也可以合成一个,如下:
public class Test {
public static void main(String[] args) {
int[] nums = {5, 7, 7, 7, 7, 8, 8, 10};
int target;
Scanner sc = new Scanner(System.in);
System.out.println("请输入目标值:");
target = sc.nextInt();
int leftIndex1 = getIndex(nums, target, true);
int rightIndex1 = getIndex(nums, target, false);
System.out.println("[" + leftIndex1 + ", " + rightIndex1 + "]");
}
private static int getIndex(int[] nums, int target, boolean flag) {
// 二分查找该数据的位置
int start = 0;
int end = nums.length - 1;
int rs = -1; // 默认设置数据不存在
while (start <= end){
int middle = (start + end) / 2;
if (target > nums[middle]){
start = middle + 1;
}else if (target < nums[middle]){
end = middle - 1;
}else{
rs = middle;
// 继续二分查找往左边再找找看
if (flag){
end = middle - 1;
}else{
start = middle + 1;
}
}
}
return rs;
}
}
四、写在最后
力扣中的一道算法题,面试的时候可能会出,可以多多练习,多敲几次,理解代码思路,如果对代码有疑问,欢迎来讨论!!!