Leetcode面试题 10.03. 搜索旋转数组-----二分搜索
题目表述
搜索旋转数组。给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次了,次数不详。请编写代码找出数组中的某个元素,假设数组元素原先是按升序排列的。若有多个相同元素,返回索引值最小的一个。
示例:
输入: arr = [15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14], target = 5
输出: 8(元素5在该数组中的索引)
二分搜搜
- 每次取中间索引判断是否和target相等,如果相等,则继续将target往左遍历,遍历到最小和target相等的索引然后返回
如果不等:则判断midVal和rVal(右边界的值),此时有三种可能:
-
midVal<rVal,则可以说明mid~right一定是递增的,则判断target是否是大于midVal并且小于等于rVal,即是否在(mid,right]这个区间,如果是,压缩区间left=mid+1,否则说明不在(mid,right]区间,压缩区间 [left,mid)
-
midVal>rVal,则可以说明leftmid是递增的,因为原数组是非递减的,要满足中间数值大于最右边数值,那么最大值一定不在midVal的左侧(假如在左侧,那么有leftk)递增,然后k+1(k<mid)~right递增。处理方式同上
-
midVal==rVal,则有两种可能 right0mid 的值都相等,或者 mid~right的值相等,无论是哪种,都可以将right舍去,压缩区间
class Solution {
public int search(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
if(arr[0] == target) return 0;
while(left <= right){
int mid = left + (right - left) / 2;
if(arr[mid] == target){
while(mid > 0 && arr[mid - 1] == target) mid--;
return mid;
}
if(arr[mid] == arr[left] ){
left++;
}
else if(arr[mid] >= arr[left]){
if(target >= arr[left] && target <= arr[mid]){
right = mid - 1;
}else{
left = mid + 1;
}
}else{
if(arr[mid] <= target && target <= arr[right]){
left = mid + 1;
}else{
right = mid - 1;
}
}
}
return -1;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了