import java.util.*;
//方发1:暴力解法。时间复杂度:O(n)
//方法二:二分法。时间复杂度:O(logn)
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] nums, int target) {
// write code here
// int length = nums.length;
// //方发1:暴力解法。一次遍历。时间复杂度:O(n)
// for(int i=0;i<length;i++){
// if(target == nums[i]){
// return i;
// }
// }
// return -1;
//方法二:二分法。
int length = nums.length;
//特殊值处理,此时长度小,可以不用进入循环,提高效率
if(length == 1){
return nums[0]==target?0:-1;
}
//目标值比第一个值nums[0]小,而且比最后一个值nums[length-1]大,eg:[6,8,10,0,2,4],目标值为5
if(nums[0]>target && nums[length-1]<target){
return -1;
}
int minValue = nums[0];//临时最小值(minValue)
int min = 1;//二分法,左指针
int max = length-1;//二分法,右指针
int mid = (min+max)/2;//二分法,中值
while(min <= max){//结束循环条件:最小值大于最大值
if(nums[mid] == target){//中值与临时最小值相等
return mid;
}else if(nums[mid] > minValue){//中值大于临时最小值(minValue),此时左边是严格升序的,由中值划分出两个区间
//如果目标值小于中值(在左边是最大值),且大于或等于最小值,此时目标值如果存在,则一定在此期间内,不可能在右边
if(target<nums[mid] && target>=nums[min]){
max = mid -1;
}else{
min = mid + 1;
}
}else {//中值小于临时最小值(minValue),此时右边是严格升序的
//如果目标值大于中值(在右边是最小值),且小于或等于最大值,此时目标值如果存在,则一定在此期间内,不可能在左边
if(target>nums[mid] && target<=nums[max]){
min = mid + 1;
}else{
max = mid - 1;
}
}
mid = (min+max)/2;//求中值
}
return -1;//循环结束,min>max,不存在目标值
}
}