zoukankan      html  css  js  c++  java
  • 33. 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.

    二、分析


      rotated之后的数组是无序的。但是,它可以以最小值为界分为前后两个子数组,而这两个数组都是有序的。我们可以首先确定要找的数target在哪个子数组,然后在哪个子数组进行binary_search即可。

      1,找最小值所在位置

     1 int getMinIndex(vector<int>& nums) {
     2         int length = nums.size();
     3         if (length == 0)
     4             return 0;
     5         int left = 0, right = length -1, mid = 0;
     6 
     7         while (left < right) {
     8             if (nums[left] < nums[right])
     9                 //return nums[left];
    10                 return left;
    11             mid = left + (right - left) / 2;
    12             if (nums[mid] <= nums[right])
    13                 right = mid;
    14             else
    15                 left = mid + 1;
    16         }
    17         //return nums[left];
    18         return left;
    19     }

      2,binary_search

     1 int binary_search(vector<int> &nums, int target, vector<int>::iterator iterLeft, vector<int>::iterator iterRight) {
     2         while (iterLeft <= iterRight) {
     3             auto mid = iterLeft + (iterRight - iterLeft) / 2;
     4             if (*mid < target)
     5                 iterLeft = mid + 1;
     6             else if (*mid > target)
     7                 iterRight = mid - 1;
     8             else
     9                 return mid - nums.begin();
    10         }
    11         return -1;
    12     }

      3, 找target的位置

     1  int search(vector<int>& nums, int target) {
     2         vector<int>::iterator iterLeft = nums.begin(), iterRight = nums.end() - 1;
     3         if (nums.size() == 0)
     4             return -1;
     5         if (*iterLeft < *iterRight) {   //array not be rotated
     6             return binary_search(nums, target, iterLeft, iterRight);
     7         }
     8         else {
     9             int index = getMinIndex(nums);
    10             if (target <= *iterRight) {
    11                 iterLeft += index;
    12                 return binary_search(nums, target, iterLeft, iterRight);
    13             }else {
    14                 iterRight = iterLeft + index;
    15                 return binary_search(nums, target, iterLeft, iterRight);
    16             }
    17         }
    18     }

      4,总结前三点,总代码如下

     1 class Solution {
     2 public:
     3     int getMinIndex(vector<int>& nums) {
     4         int length = nums.size();
     5         if (length == 0)
     6             return 0;
     7         int left = 0, right = length -1, mid = 0;
     8 
     9         while (left < right) {
    10             if (nums[left] < nums[right])
    11                 //return nums[left];
    12                 return left;
    13             mid = left + (right - left) / 2;
    14             if (nums[mid] <= nums[right])
    15                 right = mid;
    16             else
    17                 left = mid + 1;
    18         }
    19         //return nums[left];
    20         return left;
    21     }
    22 
    23     int search(vector<int>& nums, int target) {
    24         vector<int>::iterator iterLeft = nums.begin(), iterRight = nums.end() - 1;
    25         if (nums.size() == 0)
    26             return -1;
    27         if (*iterLeft < *iterRight) {
    28             return binary_search(nums, target, iterLeft, iterRight);
    29         }
    30         else {
    31             int index = getMinIndex(nums);
    32             if (target <= *iterRight) {
    33                 iterLeft += index;
    34                 return binary_search(nums, target, iterLeft, iterRight);
    35             }else {
    36                 iterRight = iterLeft + index;
    37                 return binary_search(nums, target, iterLeft, iterRight);
    38             }
    39         }
    40     }
    41 
    42     int binary_search(vector<int> &nums, int target, vector<int>::iterator iterLeft, vector<int>::iterator iterRight) {
    43         while (iterLeft <= iterRight) {
    44             auto mid = iterLeft + (iterRight - iterLeft) / 2;
    45             if (*mid < target)
    46                 iterLeft = mid + 1;
    47             else if (*mid > target)
    48                 iterRight = mid - 1;
    49             else
    50                 return mid - nums.begin();
    51         }
    52         return -1;
    53     }
    54 
    55 };
    View Code

    三、另一种“非常规”解法


      首先,我们还是找到最小值的位置,也就是两个有序子数组的分界点,记为rot。然后,取rotated数组(长度为n)的mid,那么(rot+mid)%n即unrotated数组的真实mid位置。

      然后,对这个数组进行二分查找。

     1 class Solution {
     2 public:
     3     int search(int A[], int n, int target) {
     4         int lo=0,hi=n-1;
     5         // find the index of the smallest value using binary search.
     6         // Loop will terminate since mid < hi, and lo or hi will shrink by at least 1.
     7         // Proof by contradiction that mid < hi: if mid==hi, then lo==hi and loop would have been terminated.
     8         while(lo<hi){
     9             int mid=(lo+hi)/2;
    10             if(A[mid]>A[hi]) lo=mid+1;
    11             else hi=mid;
    12         }
    13         // lo==hi is the index of the smallest value and also the number of places rotated.
    14         int rot=lo;
    15         lo=0;hi=n-1;
    16         // The usual binary search and accounting for rotation.
    17         while(lo<=hi){
    18             int mid=(lo+hi)/2;
    19             int realmid=(mid+rot)%n;
    20             if(A[realmid]==target)return realmid;
    21             if(A[realmid]<target)lo=mid+1;
    22             else hi=mid-1;
    23         }
    24         return -1;
    25     }
    26 };
  • 相关阅读:
    谷歌将用QUIC传输层技术加速互联网
    无人自助洗车机漏洞
    什么是区块链,为什么它越来越受欢迎
    域名Whois数据和隐私是最大风险
    什么原因?全球许多网络提供商推迟部署IPv6
    FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ
    C#中读写INI配置文件
    C#读取和导出EXCEL类库(可操作多个SHEET)
    Javascript刷新页面的几种方法
    用C#抓取AJAX页面的内容
  • 原文地址:https://www.cnblogs.com/letgo/p/5780692.html
Copyright © 2011-2022 走看看