1 题目解析
翻译成大白话:首先给你一个已经排序的数组,且数组元素各不相同[0,1,2,3,4,5,6,7,8];然后莫名这个数组被旋转了,使得数组变为[4,5,6,7,8,0,1,2,3]; 然后给你一个元素 target = 5,。然后从反转后的数组中找到 目标值返回其下标,如果没有找到则返回-1;
2 算法流程
核心思想,站在中间元素的角度看,被分成的左右子数组,肯定是一半有序,一半部分有序。
【第一步】我们找到了中间元素。先判断中间元素是否等于target。
【第二步】如果第一步不成立,我们需要进入有序的一边(我们可以很简单的判断出有序数组的最大最小值)。如何判断哪一边有序呢?如果我num[left](实际为4)<= nums[mid] 实际为(7)。那么左边有序。
【第三步】我们进入左半边,我们可以很简单的判断出有序数组的最大最小值。如果target 在有序数组的最大最小值的范围内。right = mid - 1;否则 left = mid +1;
3 具体代码
class Solution {
public int search(int[] nums, int target) {
if (nums.length == 1) {
return nums[0] == target ? 0 : -1;
}
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = (right + left) / 2;
if (nums[mid] == target) {
return mid;
}
// 左边有序
if (nums[left] <= nums[mid]) {
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;
}
}