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. 无法将类型为“System.DBNull”的对象强制转换为类型“System.String”

    在ERP中做业务类单据,有时候会遇到这样的报错. 无法将类型为"System.DBNull"的对象强制转换为类型"System.String"   去数据库中检 ...

  2. Python 学习之路2

    这是我在大学上机实验的作业 实验一 将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. 首先,先谈下我的设计思路: 设计思路: 1.    先需判断输入的number是不是一个数字( ...

  3. 如何优化Cocos2d-X游戏的内存

    在游戏项目优化中都会碰到一个问题,如何既能减少内存又能尽量减少包的大小?在实际项目中有些经验分享一下,事实上2D游戏中最占内存的就是图片资源,一张图片使用不同的纹理格式带来的性能差异巨大,下表是我在I ...

  4. python 小白(无编程基础,无计算机基础)的开发之路,辅助知识6 python字符串/元组/列表/字典互转

    神奇的相互转换,小白同学可以看看,很有帮助 #1.字典dict = {'name': 'Zara', 'age': 7, 'class': 'First'} #字典转为字符串,返回:<type ...

  5. rabbitmq(中间消息代理)在python中的使用

    在之前的有关线程,进程的博客中,我们介绍了它们各自在同一个程序中的通信方法.但是不同程序,甚至不同编程语言所写的应用软件之间的通信,以前所介绍的线程.进程队列便不再适用了:此种情况便只能使用socke ...

  6. 浏览器出现Cannot set property 'onclick' of null的问题

    Part1: 当js文件放在head里面时,如果绑定了onclick事件,就会出现这样的错误, 是因为W3School的写法是浏览器先加载完按钮节点才执行的js,所以当浏览器自顶向下解析时,找不到on ...

  7. Java爬虫——B站弹幕爬取

    如何通过B站视频AV号找到弹幕对应的xml文件号 首先爬取视频网页,将对应视频网页源码获得 就可以找到该视频的av号aid=8678034 还有弹幕序号,cid=14295428 弹幕存放位置为  h ...

  8. 在centos7中手动编译greenplum

    一.编译环境 Linux version 3.10.0-327.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.3 2014 ...

  9. 修改 docker image 安装目录 (解决加载大image时报错:"no space left on device")

    修改 docker image 安装目录 (解决加载大image时报错:"no space left on device" ) 基于Ubuntu16.04 docker版本: 17 ...

  10. Asteroids!-裸的BFS

    G - Asteroids! Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Subm ...