在上一篇博客中,我们深入探讨了二分搜索算法及其在寻找数组左侧边界的应用。二分搜索作为一种高效的查找方法,其核心思想在于通过不断缩小搜索范围来定位目标值。在本文中,我们将继续这一主题,不仅会回顾二分搜索的基本原理,还将重点介绍如何利用这一算法来寻找数组中目标值的右侧边界。通过对比左侧和右侧边界的搜索,我们将揭示二分搜索算法的灵活性和强大功能。无论您是在准备技术面试,还是在日常编程中寻求效率提升,本文都将为您提供宝贵的洞见。
在有序数组中寻找特定值的右侧边界是二分查找算法的一个重要变体。与寻找左侧边界类似,我们可以通过调整搜索区间的边界来实现。本文将介绍两种写法:左闭右开的常见写法和两端都闭的统一写法。
int right_bound(int[] nums, int target) {
int left = 0, right = nums.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
left = mid + 1; // 注意
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
return left - 1; // 注意
}
1. 为什么这个算法能够找到右侧边界? 答:关键在于当
nums[mid] == target
时,我们不立即返回,而是通过left = mid + 1
增大搜索区间的左边界,从而锁定右侧边界。 2. 为什么最后返回left - 1
而不是left
? 答:由于循环终止时left
和right
相等,而我们希望返回的是目标值的右侧边界,所以需要返回left - 1
。这样,当left
等于数组长度时,表示目标值不存在,返回-1
。 3. 如何处理目标值不存在的情况? 答:在循环结束后,我们检查nums[left - 1]
是否等于目标值。如果不等于,或者left - 1
索引越界,说明目标值不存在,返回-1
。
给你一个按照非递减顺序排列的整数数组
nums
,和一个目标值target
。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值target
,返回[-1, -1]
。你必须设计并实现时间复杂度为O(log n)
的算法解决此问题。
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums
是一个非递减数组-109 <= target <= 109
class Solution {
public int[] searchRange(int[] nums, int target) {
int left=0,right=nums.length-1;
int[] arr = new int[2];
if(nums.length==0)return new int[]{-1,-1};
if(nums.length==1 && nums[0]==target)return new int[]{0,0};
if(nums.length==1 && nums[0]!=target)return new int[]{-1,-1};
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]>=target)right=mid-1;
if(nums[mid]<target)left=mid+1;
}
if(left<nums.length)arr[0]= nums[left]==target? left:-1;
else arr[0]=-1;
right=nums.length-1;
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]<=target)left=mid+1;
if(nums[mid]>target)right=mid-1;
}
if(right>=0)arr[1]= nums[right]==target? right:-1;
else arr[1]=-1;
return arr;
}
}
这段代码实现了一个名为 searchRange 的方法,它用于在一个有序数组 nums 中查找给定目标值 target 的第一个和最后一个出现的索引。该方法返回一个包含两个元素的数组,第一个元素是目标值的最小索引(左侧边界),第二个元素是最大索引(右侧边界)。如果目标值不存在于数组中,则两个元素都为 -1。 以下是该方法的思路: 1. 初始化变量:
2. 处理特殊情况:
3. 寻找左侧边界:
4. 重置变量并寻找右侧边界:
5. 返回结果:
文末
通过本文的讨论,我们不仅复习了二分搜索的基本概念,还学习了如何扩展这一算法来寻找数组中元素的左侧和右侧边界。这些技巧不仅在解决特定编程问题时非常有用,也体现了算法思维在优化问题解决过程中的重要性。二分搜索算法的变体和应用广泛,从简单的查找问题到复杂的数据结构操作,都可以看到它的身影。希望本文能够帮助您更好地理解和运用二分搜索,提升您的编程技能。感谢您的阅读,期待在下一篇文章中与您再次相遇