[LeetCode] Search in Rotated Sorted Array 在旋转有序数组中搜索
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.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2]
, target = 0
Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2]
, target = 3
Output: -1
这道题让在旋转数组中搜索一个给定值,若存在返回坐标,若不存在返回 -1。我们还是考虑二分搜索法,但是这道题的难点在于不知道原数组在哪旋转了,还是用题目中给的例子来分析,对于数组 [0 1 2 4 5 6 7] 共有下列七种旋转方法(红色表示中点之前或者之后一定为有序的):
0 1 2 4 5 6 7
7 0 1 2 4 5 6
6 7 0 1 2 4 5
5 6 7 0 1 2 4
4 5 6 7 0 1 2
2 4 5 6 7 0 1
1 2 4 5 6 7 0
二分搜索法的关键在于获得了中间数后,判断下面要搜索左半段还是右半段,观察上面红色的数字都是升序的(Github 中可能无法显示颜色,参见博客园上的帖子),可以得出出规律,如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的,我们只要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内,这样就可以确定保留哪半边了,代码如下:
解法一:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = , right = nums.size() - ;
while (left <= right) {
int mid = left + (right - left) / ;
if (nums[mid] == target) return mid;
if (nums[mid] < nums[right]) {
if (nums[mid] < target && nums[right] >= target) left = mid + ;
else right = mid - ;
} else {
if (nums[left] <= target && nums[mid] > target) right = mid - ;
else left = mid + ;
}
}
return -;
}
};
看了上面的解法,你可能会产生个疑问,为啥非得用中间的数字跟最右边的比较呢?难道跟最左边的数字比较不行吗,当中间的数字大于最左边的数字时,左半段也是有序的啊,如下所示(蓝色表示中点之前一定为有序的):
0 1 2 4 5 6 7
7 0 1 2 4 5 6
6 7 0 1 2 4 5
5 6 7 0 1 2 4
4 5 6 7 0 1 2
2 4 5 6 7 0 1
1 2 4 5 6 7 0
貌似也可以做,但是有一个问题,那就是在二分搜索中,nums[mid] 和 nums[left] 还有可能相等的,当数组中只有两个数字的时候,比如 [3, 1],那该去取那一边呢?由于只有两个数字且 nums[mid] 不等于 target,target 只有可能在右半边出现。最好的方法就是让其无法进入左半段,就需要左半段是有序的,而且由于一定无法同时满足 nums[left] <= target && nums[mid] > target,因为 nums[left] 和 nums[mid] 相等,同一个数怎么可能同时大于等于 target,又小于 target。由于这个条件不满足,则直接进入右半段继续搜索即可,所以等于的情况要加到 nums[mid] > nums[left] 的情况中,变成大于等于,参见代码如下:
解法二:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = , right = nums.size() - ;
while (left <= right) {
int mid = left + (right - left) / ;
if (nums[mid] == target) return mid;
if (nums[mid] >= nums[left]) {
if (nums[left] <= target && nums[mid] > target) right = mid - ;
else left = mid + ;
} else {
if (nums[mid] < target && nums[right] >= target) left = mid + ;
else right = mid - ;
}
}
return -;
}
};
讨论:这道题的二分搜索的解法实际上是博主之前的总结帖 LeetCode Binary Search Summary 二分搜索法小结 中的第五类,也是必须要将 right 初始化为 nums.size()-1,且循环条件必须为小于等于。二分搜索法真是博大精深,变化莫测啊~
Github 同步地址:
https://github.com/grandyang/leetcode/issues/33
类似题目:
Search in Rotated Sorted Array II
Find Minimum in Rotated Sorted Array
参考资料:
https://leetcode.com/problems/search-in-rotated-sorted-array/
https://leetcode.com/problems/search-in-rotated-sorted-array/discuss/14436/Revised-Binary-Search
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Search in Rotated Sorted Array 在旋转有序数组中搜索的更多相关文章
- [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. ...
- [CareerCup] 11.3 Search in Rotated Sorted Array 在旋转有序矩阵中搜索
11.3 Given a sorted array of n integers that has been rotated an unknown number of times, write code ...
- LeetCode 33 Search in Rotated Sorted Array(循环有序数组中进行查找操作)
题目链接 :https://leetcode.com/problems/search-in-rotated-sorted-array/?tab=Description Problem :当前的数组 ...
- LeetCode Search in Rotated Sorted Array 在旋转了的数组中查找
Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...
- [LeetCode] Find Minimum 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 ...
- [LeetCode] 153. Find Minimum in Rotated Sorted Array 寻找旋转有序数组的最小值
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...
- leetcode题解: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 ...
- LeetCode 153. Find Minimum in Rotated Sorted Array寻找旋转排序数组中的最小值 (C++)
题目: Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. ( ...
- Leetcode153. Find Minimum in Rotated Sorted Array寻找旋转排序数组中最小值
假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 请找出其中最小的元素. 你可以假设数组中不存在重 ...
随机推荐
- 求解第N个素数
任务 求解第 10,0000.100,0000.1000,0000 ... 个素数(要求精确解). 想法 Sieve of Eratosthenes 学习初等数论的时候曾经学过埃拉托斯特尼筛法(Sie ...
- IIS服务器多域名证书绑定443端口解决方案
一个服务器IIS要绑定多个HTTPS站点(该方法在此之前,有进行测试其他网站域名的ssl证书,测试没有问题) 默认情况一个服务器的IIS只能绑定一个HTTPS也就是443端口 要实现多个站点对应HTT ...
- Razor语法中绑定一个值给checkbox
在ASP.NET MVC开发中,需要绑定一个值给checkbox标签,如下面写法,它们运行时是没有问题,照样能跑. 看看上面的语法,在绑定时,它却出现绿浪线.提不绑定的值is not a valid ...
- C#图片按比例缩放
C#图片按比例缩放: // 按比例缩放图片 public Image ZoomPicture(Image SourceImage, int TargetWidth, int TargetHeight) ...
- 大量数据快速导出的解决方案-Kettle
1.开发背景 在web项目中,经常会需要查询数据导出excel,以前比较常见的就是用poi.使用poi的时候也有两种方式,一种就是直接将集合一次性导出为excel,还有一种是分批次追加的方式适合数据量 ...
- JAVA 入门第二章 (面对对象)
本渣渣鸽了一个月终于有时间更新.因为有c++基础,学起来这章还是比较简单的,本章我觉得是程序猿质变课程,理解面向对象的思想,掌握面向对象的基本原则以及 Java 面向对象编程基本实现原理,熟练使用封装 ...
- java web学习总结(三十) -------------------JSTL表达式
一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...
- 图表插件Charts.js的使用
Charts.js的介绍自行百度 首先下载Charts.js,官网:http://chartjs.cn/ charts.js 托管在了github上,下载下来后加解压出src中的文件即可.其中有cha ...
- linux之cp/scp命令+scp命令详解
名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source... directory 说明:将一个档案拷贝至另一档案,或将数 ...
- 关于input标签和placeholder在IE8,9下的兼容问题
一. input常用在表单的输入,包括text,password,H5后又新增了许多type属性值,如url, email, member等等,考虑到非现代浏览器的兼容性问题,这些新的type常用在移 ...