搜索旋转排序数组
完全有序查找可以使用二分
这种部分有序也可以找到二分的点来缩减搜索半径。
只是这种二分策略能不能描述地清晰优雅。
step1 : 通过例子发现,[4,5,6,7,0,1,2] 不管切分点在哪,至少一半是有序的
step2 :因为题干说元素不重复,所以判断有序的一半数据,方式比较简单,就看尾部元素是否大于最前面元素就可以了。
step3: 如果要搜索的target在有序区间取值中,就在区间中搜索,否则在另一半搜索
step4: 注意base case要考虑,如果搜索不到,返回-1;
上面通过在有序区间中搜索的逻辑比我这个判断mid ,left, target三者的关系,堆叠的if-else要优雅的多。
public static void main(String[] args) {
int[] arr = {1,3};
int res = process(arr ,0, 0 ,arr.length-1);
System.out.println(res);
}
public static int process(int[] nums, int target, int l, int r) {
if(l > r) return -1;
if(l == r){
return nums[l] == target? l : -1;
}
if(nums[l] == target ) return l;
if(nums[r] == target) return r;
int mid = l + ((r-l)>>1);
int res = -1;
if(nums[mid] == target) return mid;
if(nums[mid] > target){
if(nums[mid] >nums[l]){
if(nums[l]< target) {
res = process(nums, target, l, mid - 1);
}
else {
res = process(nums, target, mid+1, r);
}
}else {
if(nums[l]<target){
res= process(nums, target, mid+1, r);
}
else {
res = process(nums, target,l, mid-1);
}
}
}
else if(nums[mid] < target){
if(nums[mid]>nums[l]){
if(nums[l] < target){
res = process(nums, target, mid+1, r);
}
}else {
if(nums[l]> target){
res = process(nums, target,mid+1, r);
}else {
res = process(nums, target, l, mid-1);
}
}
}
return res;
}
下面是官方的
tips:
- 优雅的找二分条件,可以节省很多if-else。这里采用有序区间法。
- 一半题解习惯用循环实现二分逻辑,我习惯用递归来实现二分。
```java
class Solution {
public int search(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;
while (l <= r) {
int mid = (l + r) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && target < nums[mid]) {
r = mid - 1;
} else {
l = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[n - 1]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
}
return -1;
作者:LeetCode-Solution 链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array/solution/sou-suo-xuan-zhuan-pai-xu-shu-zu-by-leetcode-solut/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 ```