zoukankan      html  css  js  c++  java
  • Search in Rotated Sorted Array

    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.

    两次二分,一次找到rotate的位置,一次找target。

    就是说,排序数组可能是右移了一定位数。让你在这个数组中找一个target值。当然用线性查找就没意义了。

    想这个解法需要头脑比较清晰。记得原来高中做题,老师最常说的一句话是啥?”要揣摩出题人意图啊“。。。这道题也是这样的。如果是在一个有序数组里面找一个值,那么一般都是用binarySearch。现在数组变了,(当然,还保持一些其他特点,我们下面说),能不能用binarySearch呢,或者我们改一下binarySearch呢?

    如果用binarySearch,我们在通过Low和High序号得到Mid以后,应该如何剔除一半的数据呢?

    下面是rotate后的一个有序数组的图。四边形的斜边表示数组中数值的大小。

    在这种情况下数组分了两部分,分别都是有序(递增)的。

    当我们计算了Mid以后,有两种可能,分别用Mid1和Mid2表示。

    1. 如果A[Low] < A[Mid],说明Mid落在区间1中,即图中Mid1的位置。那么,如果target小于A[Mid1],那么继续在Low和Mid1中间搜索;否则,在Mid1和High中间搜索;

    2. 如果A[Low] >= A[Mid],说明Mid落在区间2中,即图中Mid2的位置。同理,如果target小于A[Mid2],那么继续在Low和Mid2中间搜索;否则,在Mid2和High中间搜索。

    这样,平均地,我们每次剔除一半数据,时间复杂度是O(logn)。

    代码如下:

     1 public class Solution {
     2     public int search(int[] A, int target) {
     3         // Note: The Solution object is instantiated only once and is reused by each test case.
     4         //first divide find that point rotated, second one find that value
     5         assert(A!=null);
     6         int start = 0, 
     7         end = A.length-1;
     8         while(start<=end){
     9             int mid = (start+end)/2;
    10             if(A[mid]==target)
    11                 return mid;
    12             if(A[mid]>target && (A[end]>A[mid] || A[end]<target) 
    13                 || A[mid]<target && A[end]>A[mid] && A[end]<target){
    14                     end=mid-1;
    15             }else{
    16                 start=mid+1;
    17             }
    18         }
    19         return -1;
    20     }
    21 }

     第二遍:

    分类的方式很特别:

    这里是按某一部分是不是sorted 来分的。

    如果start < mid, 说明左边是sorted,那么 若 target 落在这个区间内 则 end = mid - 1;

    如果不是,说明右边是sorted,那么若target 落在这个区间内 则 start = mid + 1;

     1 public class Solution {
     2     public int search(int[] A, int target) {
     3         // Note: The Solution object is instantiated only once and is reused by each test case.
     4         //first divide find that point rotated, second one find that value
     5         int end = A.length - 1;
     6         int start = 0;
     7         while(start <= end){
     8             int mid = (end + start) / 2;
     9             if(target == A[mid]) return mid;
    10             if(A[start] <= A[mid]){//left half is sorted
    11                 if(A[start] <= target &&  target < A[mid]) end = mid - 1;
    12                 else start = mid + 1;
    13             }
    14             else{
    15                 if(A[mid] < target && target <= A[end]) start = mid + 1;
    16                 else end = mid - 1;
    17             }
    18         }
    19         return -1;
    20     }
    21 }
  • 相关阅读:
    第三周作业
    第二周作业
    计算机基础学习心得
    第三次作业
    第2次作业(指针总结)
    2018(上)C高级第0次作业
    本学期最后一次作业 总结。
    第十四、十五周作业
    第七周作业
    第六周作业
  • 原文地址:https://www.cnblogs.com/reynold-lei/p/3366298.html
Copyright © 2011-2022 走看看