leetcode - 33. Search in Rotated Sorted Array - Medium

descrition

Suppose an array sorted in ascending order 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.

解析

两种方法的时间复杂度和空间复杂度都是一样的,不过思考的思路有所不同,不过根本都是对二分查找的改进。方法 1 对应代码 int searchDirectly(vector& nums, int target); 方法 2 对应 int searchAssist(vector& nums, int target)。虽然 方法 2 对应的代码量要大一些,但思路还是值得借鉴的,这里也一并给出。

注意点:

  • 当 target 找不到的时候返回 -1
  • 可以假设数组中的元素都是唯一的 (这是代码优化的关键!)

一般的:

直接在原数组上进行二分查找。对于数组 arry[0,...,n-1] 可以将其分成两个部分 left_part = arry[0,...,imax], right_part=arry[imax+1, ..., n-1],其中 imax 指向数组中最大的元素,那么 left_part 和 right_part 都是递增的,并且 left_part 中所有的值都大于 right_part 中的值。

对于 binary search,假设 [ileft, ... , irigt] 确定 arry 中的一个子数组。下面就讨论,我们如何在每次查找中将查找空间减少一半的思路。

每次而分查找我们需要计算 imid = (ileft + iright) / 2,即中间元素的位置,将数组均分成两半。这时我们可以根据 imid 的位置来确定下一次的查找范围。

  • condition1: 如果 arry[ileft] < arry[imid] : 说明 imid 在 left_part 的 ascending 子数组中
  • condition2: 如果 arry[imid] < arry[irigh] : 说明 imid 在 rigt_part 的 ascending 子数组中

注意:因为 left_part < right_part ,因此以上两种情况是对立的。如果 ileft, imid, iright 指向的 3 个数相等,我们将无法判断 imid 处在数组的那个部分,也就无法达到划分的目的,这是题意的关键优化点。

方法 1

  • 如果 condition1 成立,那么 [ileft, ..., imid] 是递增有序的

    • 如果 target 在 [ileft, ..., imid] 区间内,则 ileft = imid-1
    • 否则 ileft = imid + 1
  • 如果 condition2 成立,那么 [imid, ..., iright] 是递增有序的
    • 如果 target 在 [imid, ..., iright] 区间内,则 ileft = imid + 1
    • 否则 iright = imid - 1

每一次查找都能使搜索空间减半。具体实现看代码,注意细节和边界条件。

方法 2

  1. 我们可以先找到数组中最小值的位置 imin,那么相对于原来递增有序的数,新的 rotated 数组中元素的位置 i' = (i + imin)%n。比如 4 5 6 7 0 1 2, imin = 4,相当于原数组 0 1 2 4 5 6 7 循环右移了 imin 步。找最小值的位置也是使用折半查找的思想,时间复杂度 O(log(n))。
  2. 针对原数组 0 1 2 4 5 6 7 使用而分查找,每次而分查找比较时,使用 i' = (i + imin)%n 计算真是的 middle 位置。这样可以达到减办的效果。时间复杂度 O(log(n)) 。

具体实现查看代码。虽然这样的方法比钱前一种方法来说代码量大,实际上做了两次而分查找,但这里新地址的映射方式是个很好的思考思路。

code


#include <iostream>
#include <vector>
#include <algorithm> using namespace std; class Solution{
public:
int search(vector<int>& nums, int target){
// You may assume no duplicate exists in the array.
//return searchDirectly(nums, target);
return searchAssist(nums, target);
} // time-O(log(n)), space-O(1)
int searchDirectly(vector<int>& nums, int target){
int ileft = 0;
int iright = nums.size()-1;
while(ileft <= iright){
int imid = (ileft+iright)/2;
if(nums[imid] == target){
return imid;
} // nums[imid] != target
if(nums[ileft] <= nums[imid]){
// nums[ileft,...,imid] is ascending
// Note: don't forget to check nums[ileft] == target
if(nums[ileft] <= target && target < nums[imid]){
iright = imid - 1;
}else{
ileft = imid + 1;
} }else{
// nums[imid] < nums[iright]
// nums[imid,...,iright] is ascending
// Note: don't forget to check target == nums[iright]
if(nums[imid] < target && target <= nums[iright]){
ileft = imid + 1;
}else{
iright = imid - 1;
}
} } return -1;
} // time-O(log(n)), space-O(1)
int searchAssist(vector<int>& nums, int target){
if(nums.empty())
return -1; // the number of rotated of each element in nums
int irotated = findMinInRotatedArray(nums);
int n = nums.size(); int ileft = 0;
int iright = nums.size() - 1;
while(ileft <= iright){
int imid = (ileft + iright) / 2;
int imidReal = (imid + irotated) % n; // calculate the real index of middle value
if(nums[imidReal] == target){
return imidReal;
}else if (nums[imidReal] < target){
ileft = imid + 1;
}else{
// nums[imidReal] > target
iright = imid - 1;
}
} return -1;
} int findMinInRotatedArray(vector<int>& nums){
if(nums.empty())
return -1;
if(nums[0] < nums[nums.size()-1]) // nums in ascending
return 0; // binary search
int ileft = 0;
int iright = nums.size() - 1;
while(ileft+1 < iright){
int imid = (ileft + iright) / 2;
if(nums[ileft] < nums[imid]){
ileft = imid;
}else{
// nums[imid] < nums[iright]
iright = imid;
}
} // ileft point to the maximum
// iright point to the minimum return iright;
}
}; int main()
{
return 0;
}

[array] leetcode - 33. Search in Rotated Sorted Array - Medium的更多相关文章

  1. LeetCode 33 Search in Rotated Sorted Array [binary search] <c++>

    LeetCode 33 Search in Rotated Sorted Array [binary search] <c++> 给出排序好的一维无重复元素的数组,随机取一个位置断开,把前 ...

  2. [LeetCode] 33. Search in Rotated Sorted Array 在旋转有序数组中搜索

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  3. LeetCode 33. Search in Rotated Sorted Array(在旋转有序序列中搜索)

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  4. leetCode 33.Search in Rotated Sorted Array(排序旋转数组的查找) 解题思路和方法

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  5. LeetCode 33.Search in Rotated Sorted Array(M)

    题目: Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. ( ...

  6. leetcode 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 migh ...

  7. Java [leetcode 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 ...

  8. [leetcode]33. Search in Rotated Sorted Array旋转过有序数组里找目标值

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  9. LeetCode 33 Search in Rotated Sorted Array(循环有序数组中进行查找操作)

    题目链接 :https://leetcode.com/problems/search-in-rotated-sorted-array/?tab=Description   Problem :当前的数组 ...

随机推荐

  1. 照虎画猫写自己的Spring——依赖注入

    前言 上篇<照虎画猫写自己的Spring>从无到有讲述并实现了下面几点 声明配置文件,用于声明需要加载使用的类 加载配置文件,读取配置文件 解析配置文件,需要将配置文件中声明的标签转换为F ...

  2. NGUI_01

    序言:这是张三疯第一次开始NGUI插件的学习,刚开始学习,肯定有很多漏洞,后期会及时的补上的.希望大家可以见谅,希望大佬多多指教. 扩充:为提供和我一样的小白找不到免费的NGUI插件,这里分享百度网盘 ...

  3. 解决阿里云服务器3306端口无法访问的问题(windows server 2008r2)

    3306端口一般是指mysql数据的默认端口.郁闷了几天的问题,远程无法连接服务器上的mysql服务.今天终于得到彻底解决. 首先,你要确保在服务器上安装好Mysql,并能本地启动.修改密码(如不知道 ...

  4. 简单购物车程序(Python)

    #简单购物车程序:money_all=0tag=Trueshop_car=[]shop_info={'apple':10,'tesla':100000,'mac':3000,'lenovo':3000 ...

  5. HDU1284--完全背包

    钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  6. webMagic解析淘宝cookie 提示Invalid cookie header

    webMagic解析淘宝cookie 提示Invalid cookie header 在使用webMagic框架做爬虫爬取淘宝极又家页面时候一直提醒cookie设置不可用如下图 淘宝的验证特别严重,c ...

  7. stm32串口接收中断协议解析

    借鉴了文章:<stm32串口中断接收方式详细比较> 文章地址:http://blog.csdn.net/kevinhg/article/details/40186169 串口的配置这里不做 ...

  8. linux apt-cache使用方法

    apt-cache是linux下的一个apt软件包管理工具,它可查询apt的二进制软件包缓存文件.APT包管理的大多数信息查询功能都可以由apt-cache命令实现,通过apt-cache命令配合不同 ...

  9. Sagit.Framework For IOS 开发框架入门开发教程2:一行代码实现引导页

    前言: 开篇比较简单:Sagit.Framework For IOS 开发框架入门开发教程1:框架下载与环境配置 第二篇教程之前写了一半,感觉不太好写,而且内容单纯介绍API,要说的很多,又枯燥乏味. ...

  10. springboot(一)

    1,使用springboot开发需要以下配置: : Maven | Gradle | Ant | Starters code工具:IDE | Packaged | Maven | Gradle 系统要 ...