classSolution{publicintsearch(int[] nums,int target){//k指向旋转数组前半段的最后一个元素int k =-1;int n = nums.length -1;//ans返回结果int ans =-1;//寻找k,k的特点是k的元素大于k+1for(int i =0; i < nums.length -1; i++){if(nums[i]> nums[i+1]){
k = i;break;}}//如果左半部分找到了targetif(binSearch(nums,0, k, target)>=0){
ans =binSearch(nums,0, k, target);}//如果右半部分找到了targetif(binSearch(nums, k+1, n, target)>=0){
ans =binSearch(nums, k+1, n, target);}return ans;}intbinSearch(int[] num,int l,int r,int target){while(l <= r){int mid = l +(r - l)/2;if(num[mid]== target){return mid;}elseif(num[mid]< target){
l = mid +1;}else{
r = mid -1;}}return-1;}}
classSolution{publicintsearch(int[] nums,int target){int n = nums.length;int left =0, right = n -1;if(n ==0)return-1;if(n ==0)return nums[0]== target ?0:-1;while(left <= right){int mid = left +(right - left )/2;if(nums[mid]== target){return mid;}//[+++++---],左右两部分均递增。// |(|代表mid)//如果nums[mid] > nums[0] ,说明前面一直到mid都为递增有序//>=是因为可能只有两个元素[3, 1]target = 1,mid = nums[0]if(nums[mid]>= nums[0]){//如果target介于0和mid之间if(target >= nums[0]&& target < nums[mid]){
right = mid -1;}else{
left = mid +1;}//mid落在了右半区}else{if(target > nums[mid]&& target <= nums[right]){
left = mid +1;}else{
right = mid -1;}}}return-1;}}
3.复杂度分析:时间0(log(n))空间0(1).
方法3
1.思路:使用两次二分,一次寻找旋转点(左边最后一个点),一次寻找target
2.代码:
classSolution{publicintsearch(int[] nums,int target){int n = nums.length;if(n ==0)return-1;if(n ==1)return nums[0]== target ?0:-1;int l =0, r = n -1;//由于可能在下标0出旋转,所以要找左边的最后一个点while(l < r){int mid = l +(r - l +1)/2;//mid位于右半区if(nums[mid]>= nums[0]){
l = mid;}else{
r = mid -1;}}//如果target位于左边,则改变l rif(target >= nums[0]){
l =0;//位于右边改变r}else{
l = l +1;
r = n -1;}//第二次二分寻找targetwhile(l < r){int mid = l +(r - l +1)/2;if(nums[mid]> target){
r = mid -1;}else{
l = mid;}}//不能return nums[l] == target ? l : -1;因为,当测试案例为【1,3】, target = 0时候//target位于右,执行,l = l + 1,此时l = n,r = n-1,不会执行第二次二分,//return nums[l] == target ? l : -1会报数组下标溢出错误。//当数组是递增顺序时,target小于第一个元素,一定返回-1.return nums[r]== target ? r :-1;}}
方法1:1.思路:旋转数组的特点是从数组中的元素分两部分,[0, k], [k+1, n]都递增,且nums[k] > nums[k+1].所以只需要找到k的位置,分别对两部分二分查找即可。2.代码:class Solution { public int search(int[] nums, int target) { //k指向旋转数组前半段的最后一个元素 int k = -1; int n = nums.length - 1;