zoukankan      html  css  js  c++  java
  • 解题报告:LeetCode Search in Rotated Sorted Array II(循环数字查找)

    题目出处:https://leetcode.com/problems/search-in-rotated-sorted-array-ii/

    题意描述:

    给定一循环数组,查找目标值是否在该数组中。

    解决思路:

    由于这是Search in Rotated Sorted Array的后续题目,因此我想为了解决这道题我们有必要先解决上一道题。也就是不重复的情况下的查找。由于数组不重复,因此我们只需要先找出突变的位置即可调用经典的二分查找。而查找突变位置也可以通过二分的方式给出。附代码如下(其中find_mid函数为寻找突变点的函数,binary_search为普通的二分查找,search在调用find_mid获得突变点的位置后调用binary_search查找并获取结果)。

     1 class Solution {
     2 public:
     3     int find_mid(vector<int>& nums, int l, int r)
     4     {
     5         if(l == r)
     6             return r;
     7         int pos = (r+l)/2;
     8         if(nums[pos] >= nums[0] && nums[pos+1] < nums[0])
     9             return pos;
    10         else if(nums[pos] < nums[0])
    11             return find_mid(nums, l, pos-1);
    12         else
    13             return find_mid(nums, pos+1, r);
    14     };
    15 
    16     int binary_search(vector<int>& nums, int target, int l, int r)
    17     {
    18         if(l > r)
    19             return -1;
    20 
    21         int mid = (l+r)/2;
    22         if(nums[mid] == target)
    23             return mid;
    24         else if(nums[mid] < target)
    25             return binary_search(nums, target, mid+1, r);
    26         else
    27             return binary_search(nums, target, l, mid-1);
    28     }
    29 
    30     int search(vector<int>& nums, int target) {
    31         int mid = find_mid(nums, 0, nums.size()-1);
    32         if(nums[0] > target)
    33         {
    34             if(mid < nums.size()-1)
    35                 return binary_search(nums, target, mid+1, nums.size()-1);
    36             else
    37                 return -1;
    38         }
    39         else
    40             return binary_search(nums, target, 0, mid);
    41     };
    42 };
    View Code

    上述代码在OJ果断AC,将这道题解决后,我们只需要将之修改为可处理重复情况即可。首先我们尝试将上述代码的稍作修改提交试试效果。修改后的代码如下:

     1 class Solution {
     2 public:
     3     int find_mid(vector<int>& nums, int l, int r)
     4     {
     5         if(l == r)
     6             return r;
     7         int pos = (r+l)/2;
     8         if(nums[pos] >= nums[0] && nums[pos+1] < nums[0])
     9             return pos;
    10         else if(nums[pos] < nums[0])
    11             return find_mid(nums, l, pos-1);
    12         else
    13             return find_mid(nums, pos+1, r);
    14     };
    15 
    16     int binary_search(vector<int>& nums, int target, int l, int r)
    17     {
    18         if(l > r)
    19             return -1;
    20 
    21         int mid = (l+r)/2;
    22         if(nums[mid] == target)
    23             return mid;
    24         else if(nums[mid] < target)
    25             return binary_search(nums, target, mid+1, r);
    26         else
    27             return binary_search(nums, target, l, mid-1);
    28     }
    29 
    30     bool search(vector<int>& nums, int target) {
    31         int mid = find_mid(nums, 0, nums.size()-1);
    32         int pos;
    33         if(nums[0] > target)
    34         {
    35             if(mid < nums.size()-1)
    36                 pos =  binary_search(nums, target, mid+1, nums.size()-1);
    37             else
    38                 pos = -1;
    39         }
    40         else
    41             pos = binary_search(nums, target, 0, mid);
    42         return (pos != -1);
    43     };
    44 };
    View Code

    果然,上述代码跪了,对样例分析可知,在首位和中间的值均相等时,函数无法确定突变点在左半区间还是右半区间。于是我们需要对此特殊情况进行处理。我的做法是判定这三个值均相等时修改上界或下界,再递归调用函数求解。代码如下:

     1 class Solution {
     2 public:
     3     int find_mid(vector<int>& nums, int l, int r)
     4     {
     5         if(l == r)
     6             return r;
     7         int pos = (r+l)/2;
     8         if(nums[pos] >= nums[0] && nums[pos+1] < nums[0])
     9             return pos;
    10         else if(nums[pos] < nums[0])
    11             return find_mid(nums, l, pos-1);
    12         else if(nums[pos] > nums[0])
    13             return find_mid(nums, pos+1, r);
    14         else
    15         {
    16             if(nums[r] == nums[pos])
    17                 r --;
    18             else
    19                 l ++;
    20             return find_mid(nums, l, r);
    21         }
    22     };
    23 
    24     int binary_search(vector<int>& nums, int target, int l, int r)
    25     {
    26         if(l > r)
    27             return -1;
    28 
    29         int mid = (l+r)/2;
    30         if(nums[mid] == target)
    31             return mid;
    32         else if(nums[mid] < target)
    33             return binary_search(nums, target, mid+1, r);
    34         else
    35             return binary_search(nums, target, l, mid-1);
    36     }
    37 
    38     bool search(vector<int>& nums, int target) {
    39         int mid = find_mid(nums, 0, nums.size()-1);
    40         int pos;
    41         if(nums[0] > target)
    42         {
    43             if(mid < nums.size()-1)
    44                 pos =  binary_search(nums, target, mid+1, nums.size()-1);
    45             else
    46                 pos = -1;
    47         }
    48         else
    49             pos = binary_search(nums, target, 0, mid);
    50         return (pos != -1);
    51     };
    52 };

    上述代码获得了AC。OK,吃饭去了。

    此博客中的内容均为原创或来自网络,不用做任何商业用途。欢迎与我交流学习,我的邮箱是b-liu14@mails.tsinghua.edu.cn
  • 相关阅读:
    Vuforia7+Unity2017.3.f3实践练习
    pureMVC+unity
    sql语法小结
    ScreenToViewportPoint,WorldToViewportPoint,ViewportToWorldPoint的运用,实现一个简单的对三维中物体的拖拽移动效果
    Unity游戏开发学习之路——数据持久化
    Unity游戏开发之路上的那些坑——NullReferenceException
    ffmpeg-音频视频处理
    微信开发之(五)接收语音识别结果
    微信开发之(五)获取media_id的值
    微信开发之(五)微信获取自定义菜单
  • 原文地址:https://www.cnblogs.com/bill-liu/p/5049087.html
Copyright © 2011-2022 走看看