Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,1,2,4,5,6,7]
might become [4,5,6,7,0,1,2]
).
You are given a target value to search. If found in the array return its index, otherwise return -1
.
You may assume no duplicate exists in the array.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2] , target = 0 Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2] , target = 3 Output: -1
这道题让在旋转数组中搜索一个给定值,若存在返回坐标,若不存在返回-1。我们还是考虑二分搜索法,但是这道题的难点在于我们不知道原数组在哪旋转了,我们还是用题目中给的例子来分析,对于数组[0 1 2 4 5 6 7] 共有下列七种旋转方法:
0 1 2 4 5 6 7
7 0 1 2 4 5 6
6 7 0 1 2 4 5
5 6 7 0 1 2 4
4 5 6 7 0 1 2
2 4 5 6 7 0 1
1 2 4 5 6 7 0
二分搜索法的关键在于获得了中间数后,判断下面要搜索左半段还是右半段,我们观察上面红色的数字都是升序的,由此我们可以观察出规律,如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的,我们只要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内,这样就可以确定保留哪半边了,代码如下:
package com.gaoxue.LeetCode; public class RotatedSortedArray { public int search(int[] A, int target) { if (A.length == 0) return -1; int L = 0, R = A.length-1; if (target < A[L] && target > A[R]) return -1; //首先判断哪一部分是有序的,然后对有序数组进行二分查找再判断target保留在哪一半. while (L <= R) { int M = (L + R)/2; if(A[M]==target) return M; else if (A[M] <= A[R]) { if (target > A[M] && target <= A[R]) { L = M+1; } else { R = M-1; } } else { if (target < A[M] && target >= A[L]) { R = M-1; } else { L = M+1; } } } return -1; } public static void main(String[] args) { System.out.println(new RotatedSortedArray().search(new int[] {4,5,6,7,0,1,2}, 0)); } }
这样的二分查找大家不陌生吧,那么下面的实现呢......
package com.gaoxue.LeetCode; public class RotatedSortedArray { public int search(int[] A, int target) { if (A.length == 0) return -1; int L = 0, R = A.length-1; if (target < A[L] && target > A[R]) return -1; while (L < R) { int M = (L + R)/2; if (A[M] <= A[R]) { if (target > A[M] && target <= A[R]) { L = M+1; } else { R = M; } } else { if (target <= A[M] && target >= A[L]) { R = M; } else { L = M+1; } } } if (A[L] == target) return L; else return -1; } public static void main(String[] args) { System.out.println(new RotatedSortedArray().search(new int[] {4,5,6,7,0,1,2}, 0)); } }
还是你熟悉的二分查找吧,但可能对大多数人这道题并不是呢么好做,原因就在于对二分查找思想的本质理解的不够深刻,怎样才算把一个知识学懂呢,首先自然是不能被它发生的变化所迷惑,其次就是能够熟练应用啦,那么就从这道题二分查找的认识开始吧~