💛题目描述:
给一个按照升序排序的数组,然后在某一索引处旋转,求出给定数组中target的下标并返回。
给定的数组是旋转之后的数组
数组中的每一个元素都是独一无二的;
🧡代码验证:
按照题目的意思,就是求给定数组中targe值得索引号,并返回
利用js中数组得 indexOf方法:
function search(nums,target){
let index = nums.indexOf(target);
if(index != -1){
return index
}
else{
return -1
}
乍一看这道题怎么可能是中等难度题目呢?一定没有这么简单
上述代码的时间复杂度是O(n)
现在需要实现时间复杂度为O(logn) ------ 二分查找
一开始不明白为什么是给的是旋转后得数组,那旋转还有什么意义呢?
原来升序后旋转一次后,新的数组 前半段或者后半段 依然是有序的;
💖思路:
💜先判断mid的前半段是有序的还是后半段是有序的
这里要注意的就是数组原本是升序的,也就是说 if(nums[mid] < nums[right]) 那么mid之后也就是后半段是有序的,
💜再判断 target 是在有序数列段还是无序序列段,然后移动指针
function search(nums,target){
let left = 0;
let right = nums.length -1;
let mid = 0;
while(left <= right){
// 求中间的索引 这么写是为了防止栈溢出
mid = left + ((right-left) >>1)
if(nums[mid] == target){
return mid;
}
//说明前半段是有序的
if(nums[mid] > muns[left) {
//如果target在前半段
if(target>=nums[left] && target < nums[mid] ){
right = mid-1;
}else{left = mid+1 }
}
//否则在后半段
else{
if(target >nums[mid] && target <=nums[right]){
left = mid+1
}else{right = mid-1 }
}
}
return -1
}
踩坑总结:
求中间的索引号:mid = (left + right) /2 ,但是在JS中,并不能表示任意大的数,范围是MAX_VALUE~MIN_VALUE;left < infinity right < infinity 并不能保证(left + right)<infinity;
在JS中 mid = left + (right - left ) / 2 会报错
应该写成 mid = left + ((right - left) >>1)