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的更多相关文章

  1. LeetCode: Search in Rotated Sorted Array II 解题报告

    Search in Rotated Sorted Array II Follow up for "LeetCode: Search in Rotated Sorted Array 解题报告& ...

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

    Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...

  3. [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 ...

  4. LeetCode——Search in Rotated Sorted Array II

    Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this ...

  5. [leetcode]Search in Rotated Sorted Array II @ Python

    原题地址:https://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/ 题意: Follow up for "Sea ...

  6. [LeetCode] Search in Rotated Sorted Array II [36]

    称号 Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would t ...

  7. [Leetcode] search in rotated sorted array ii 搜索旋转有序数组

    Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...

  8. [LeetCode] Search in Rotated Sorted Array II 二分搜索

    Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...

  9. LeetCode Search in Rotated Sorted Array II -- 有重复的旋转序列搜索

    Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...

随机推荐

  1. 输入 cc -c 指令出现问题

    mac 命令行里 编译 链接 出现xcrun: error: active developer path mac cc 编译出现 xcrun: error: active developer path ...

  2. 函数return/获取元素样式/封装自己的库

    一:函数return <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type&qu ...

  3. spring中的 classpath* 存在可移植性问题

    classpath* 的可移植性问题,许多人都应该遇到过了.下面就是一个例子(使用的是spring4.1.5和mybatis3.2.8): <bean id="sqlSessionFa ...

  4. 问题解决——ShowWindow不显示窗口

    配合任务栏通知区域. //MFC对话框程序 void CXXXDlg::OnShowHideUi() { // TODO: 在此添加命令处理程序代码 m_bShown=!m_bShown; ShowW ...

  5. 问题解决——MFC SDI程序 CFormView中控件随窗口缩放

    从来都是做对话框程序,这次想做个SDI的程序,想着用一下带Robbin界面的office2007风格,就不用使用那些花钱的商业控件/UI库了. 如果你不想看我打的文字,可以直接拷走代码,自己声明上定义 ...

  6. 数据结构--栈的应用(表达式求值 nyoj 35)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35 题目: 表达式求值 时间限制:3000 ms | 内存限制:65535 KB描述 AC ...

  7. oracle 11g dataguard创建的简单方法

    oracle 10g可以通过基于备份的rman DUPLICATE实现dataguard,通过步骤需要对数据库进行备份,并在standby侧进行数据库的恢复.而到了11g,oracle推出了Dupli ...

  8. Hadoop 文件的数量怎么比block的数量多?

    Total files:    23 Total symlinks:        0 Total blocks (validated):    22 (avg. block size 117723 ...

  9. 【温故而知新-Javascript】窗口效果 (全屏显示窗口、定时关闭窗口)

    1.全屏显示窗口 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...

  10. SQL里面如何取得前N条数据?

    select * from table order by id limit 10 运用limit可以获取前N个数据