Suppose a sorted array 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.
编程属于计算机科学,计算机科学的理念有优秀的设计,但是不管是什么,归根结底都是0,1问题,这就是我们的根基。
题目,有问题,原子化,解决~~~
注意:算法题和我们的日常生活一样,应当先归类,再寻找相应的解题思路。比如这个题目,属于查找,你想到了什么?
和其他题目一样,没有时间复杂度的要求,所以o(n):
1 public int search(int[] A, int target) { 2 3 int length = A.length; 4 int i = 0; 5 int reslut = -1; 6 while (i < length) { 7 if (A[i] == target) { 8 reslut = i; 9 break; 10 } 11 i++; 12 } 13 return reslut; 14 }
查找算法中,以二分查找较为高效,这是我们很自然可以想到的。虽然本题已经不是基本的有序情况,不过依然可以使用二分查找的概念来做这个题,二分查找的理念来源于递归的思路,首先要确定的就是部分与整体的关联性!
以为在本题中你不知道pivot,数组肯定是由2个升序的排列,但是你不知道中间的连接点在哪里,如果将数组一分为二,那么将是一个为升序数组,另一个于初始情况相同。不难理解这样完全可以递归操作了,现在要做的是区分二者。
升序情况A[0]<A[length];非升序情况(由于前提的循环二字)A[0]>A[length];
当然如果两个都是升序了,那说明我们已经完美的分离了2个升序,更加方便了。
这样算法复杂度就降到了o(logn):
1 2 public int search(int[] A, int target) { 3 int i = 0; 4 int length = A.length; 5 return RotatedBinarySearch(A, i, length - 1, target); 6 } 7 8 // 普通二分查找 9 public int BinarySearch(int[] A, int a, int b, int target) { 10 11 int middle = (a + b) / 2; 12 if (A[middle] == target) { 13 return middle; 14 } else if ((A[middle] < target) && (middle + 1 <= b)) { 15 return BinarySearch(A, middle + 1, b, target); 16 } else if ((A[middle] > target) && (middle - 1 >= a)) { 17 return BinarySearch(A, a, middle - 1, target); 18 } else { 19 return -1; 20 } 21 } 22 23 // 循环数组的二分查找 24 public int RotatedBinarySearch(int[] A, int a, int b, int target) { 25 26 int middle = (a + b) / 2; 27 if (A[middle] == target) { 28 return middle; 29 } else if (middle + 1 <= b && A[middle + 1] <= A[b]) { 30 if ((A[middle + 1] <= target) && (target <= A[b])) { 31 return BinarySearch(A, middle + 1, b, target); 32 } else if (middle - 1 >= a) { 33 return RotatedBinarySearch(A, a, middle - 1, target); 34 } else { 35 return -1; 36 } 37 } else if (middle - 1 >= a && A[middle - 1] >= A[a]) { 38 if ((A[middle - 1] >= target) && (target >= A[a])) { 39 return BinarySearch(A, a, middle - 1, target); 40 } else if (middle + 1 <= b) { 41 return RotatedBinarySearch(A, middle + 1, b, target); 42 } else { 43 return -1; 44 } 45 46 } else { 47 return -1; 48 } 49 }