LeetCode:Search in Rotated Sorted Array I II
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
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. 本文地址
分析:顺序查找肯定是可以的,可不可以找出效率更高的查找算法?其实二分查找也可以用在这里。那么和普通的二分查找有什么区别呢?
- 当target < A[middle]时,普通二分查找是让查找区间右边界iend = middle - 1,这一题中不能直接这么操作,因为我们查找的元素有可能在middle的后半段,例如在5 6 7 8 9 1 2 3中查找2,中间元素时8, 虽然2 < 8, 但是我们还是要在middle后半段查找,那么什么时候会出现这种情况呢,要满足三个条件:
a、查找区间的尾部元素小于首部元素,这表示查找区间不是全部有序的,
b、target不大于查找区间的尾部元素,这表示target在旋转前数组的前半部分,
c、中间元素要大于查找区间尾部元素,这表示中间元素在旋转前数组的后半部分。
如果没有同时满足这三个条件那么我们要去middle的前半段查找。
- 当target > A[middle]时,普通二分查找要到middle后半段查找,这一题中比如 在7 8 9 1 2 3 5 6中查找8, 中间元素时1,8 > 1但是还是需要到前半段查找。到前半段查找时,也需要同时满足三个条件:
a、查找区间的尾部元素小于首部元素,这表示查找区间不是全部有序的
b、target大于查找区间的尾部元素,这表示target在旋转前数组的后半部分
c、中间元素要小于查找区间尾部元素,这表示中间元素在旋转前数组的前半部分。
如果没有同时满足这三个条件那么我们要去middle的后半段查找。
- 当target = A[middle]时 直接返回查找结果
class Solution {
public:
int search(int A[], int n, int target) {
int istart = 0, iend = n-1, mid;
while(istart <= iend)
{
mid = (istart + iend) / 2;
if(A[mid] > target)
{
if(A[iend] < A[istart] && target <= A[iend] && A[mid] > A[iend])
istart = mid + 1;
else iend = mid - 1;
}
else if(A[mid] < target)
{
if(A[iend] < A[istart] && target > A[iend] && A[mid] < A[iend])
iend = mid - 1;
else istart = mid + 1;
}
else return mid;
}
return -1;
}
};
LeetCode:Search in Rotated Sorted Array II
Follow up for "Search in Rotated Sorted Array":
What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.
分析:上一题的所有分析是基于数组中没有重复元素的,如果存在重复元素,情况会如何呢?
- 修正条件a:对于上一题的三个条件中的a条件,当查找区间尾部元素等于首部元素时,也有可能表示查找区间不是有序的,比如1 1 1 3 1
- 修正条件c:当中间元素等于尾部元素时,也可能满足上面的条件,比如target = 3,数组为1 1 1 3 1,或者target = 1,数组为3 3 3 1 3
- 当三个条件都满足时,如果中间元素等于尾部元素,我们不能确定是向哪个方向继续查找,例如target = 3,查找区间为1 1 1 3 1和1 3 1 1 1都满足target > 中间元素时的三个条件,但是两个区间分别是向middle的不同方向查找,因此此时查找区间不能折半,只能让区间的右边界减1
class Solution {
public:
bool search(int A[], int n, int target) {
int istart = 0, iend = n-1, mid;
while(istart <= iend)
{
mid = (istart + iend) / 2;
if(A[mid] > target)
{
if(A[iend] <= A[istart] && target <= A[iend] && A[mid] >= A[iend])
{
if(A[mid] == A[iend])
iend--;
else istart = mid + 1;
}
else iend = mid - 1;
}
else if(A[mid] < target)
{
if(A[iend] <= A[istart] && target > A[iend] && A[mid] <= A[iend])
{
if(A[mid] == A[iend])
iend--;
else iend = mid - 1;
}
else istart = mid + 1;
}
else return true;
}
return false;
}
};
在leetcode的discuss里看到了另一种思路的解法,通过判断查找区间首部元素和中间元素的关系来判断查找区间的哪一部分是有序的
没有重复元素的情形下:
- 如果中间元素大于首部元素,那么表明查找区间左半部分是有序的,然后再根据target是否在有序的一部分来决定接下来查找的方向
- 如果中间元素小于首部元素,那么查找区间有半部分是有序的,然后再根据target是否在有序的一部分来决定接下来查找的方向
- 如果中间元素等于首部元素,此时只有可能是查找区间包含一个或两个元素的情形,让左边界加1继续查找即可(相当于左边界 = middle + 1,因为此时midlle等于左边界)
包含重复元素的情形:
- 前两种情况一样,最后一种情况当中间元素等于首部元素时,查找区间有可能不再只包含一个或两个元素,此时没法判断哪一部分有序,只能将查找区间左边界加1,其实操作和上面是相同的
两题都可以用以下代码(稍微修改返回值)
class Solution {
public:
bool search(int A[], int n, int key) {
int l = 0, r = n - 1;
while (l <= r) {
int m = l + (r - l)/2;
if (A[m] == key) return true; //return m in Search in Rotated Array I
if (A[l] < A[m]) { //left half is sorted
if (A[l] <= key && key < A[m])
r = m - 1;
else
l = m + 1;
} else if (A[l] > A[m]) { //right half is sorted
if (A[m] < key && key <= A[r])
l = m + 1;
else
r = m - 1;
} else l++;
}
return false;
}
};
参考资料:http://oj.leetcode.com/discuss/223/when-there-are-duplicates-the-worst-case-is-could-we-do-better
【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3465240.html
LeetCode:Search in Rotated Sorted Array I II的更多相关文章
- LeetCode: Search in Rotated Sorted Array II 解题报告
Search in Rotated Sorted Array II Follow up for "LeetCode: Search in Rotated Sorted Array 解题报告& ...
- [LeetCode] Search in Rotated Sorted Array II 在旋转有序数组中搜索之二
Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...
- [LeetCode] Search in Rotated Sorted Array I (33) && II (81) 解题思路
33. Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you be ...
- LeetCode——Search in Rotated Sorted Array II
Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this ...
- [leetcode]Search in Rotated Sorted Array II @ Python
原题地址:https://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/ 题意: Follow up for "Sea ...
- [LeetCode] Search in Rotated Sorted Array II [36]
称号 Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would t ...
- [Leetcode] search in rotated sorted array ii 搜索旋转有序数组
Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...
- [LeetCode] Search in Rotated Sorted Array II 二分搜索
Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...
- LeetCode Search in Rotated Sorted Array II -- 有重复的旋转序列搜索
Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...
随机推荐
- android 进程间通信---Service Manager(1)
Bind机制由4个部分组成.bind驱动,Client,ServiceManager &Service 1.Bind其实是一个基于linux系统的驱动,目的是为了实现内存共享. bind驱动的 ...
- 迷宫问题求解之“A*搜索”(二)
摘要:在迷宫问题求解之"穷举+回溯"(一)这篇文章中采用"穷举+回溯"的思想,虽然能从迷宫的入口到出口找出一条简单路径,但是找出来的不是最优路径.因此本文采用A ...
- html页面识别当前系统和语言
项目中需要一个下载功能,根据系统跳转到不同的页面,如iphone跳转到IOS页面,android跳转到android页面. 下面为页面判断页面: <!DOCTYPE HTML> <h ...
- centos7 拨号之后添加路由
问题:拨号主机再自动拨号(/sbin/ifdown ppp0;/sbin/ifup ppp0)之后,无法上网(没有添加路由) 思路:在拨号程序中添加路由代码 vim /sbin/ifup { slee ...
- 手机打开PC端网址自动跳转到手机站代码
<script>function uaredirect(murl){ try { if(document.getElementById("bdmark") != nul ...
- 【Ext.Net学习笔记】02:Ext.Net用法概览、Ext.Net MessageBus用法、Ext.Net布局
Ext.Net用法概览 Ext.Net还是很强大,如果运用熟练可以极大的提高编程效率.如果你也要学习Ext.Net,原文博主推荐书籍:<Ext.Net Web 应用程序开发教程>,是英文的 ...
- 项目回顾1-图片上传-form表单还是base64-前端图片压缩
第一个项目终于上线了,是一个叫亲青筹的公益众筹平台,微信端,电脑端还有后台界面大部分都是我完成的,几个月过来,感觉收获了很多,觉得要总结一下. 首先想到的是图片上传的问题.在通常表单数据都是ajax上 ...
- POJ 1754 Splay
单点更新,区间最值,用来练Splay刚好. 将位置作为排序的规则,利用Splay不会改变顺序的特点,求某一段区间[l,r]的最值时,将l-1伸展到根,将r+1伸展到l-1的右子树,这时r+1的左子树就 ...
- WWW压缩解压缩
unity的WWW参考文档:http://game.ceeger.com/Script/WWW/WWW.html 在unity中把资源打包成Assetbundle其实把资源通过 LZMA 压缩成二进制 ...
- uGUI练习(六) ScrollView
练习目标 练习uGUI的滑动组件 一.相关组件 ScrollRect Mask Grid Layout Group Scrollbar 二.步骤 1.创建一个Panel,命名为ScrollRect,添 ...