| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> LeetCode 33. 搜索旋转排序数组(C++) -> 正文阅读 |
|
[数据结构与算法]LeetCode 33. 搜索旋转排序数组(C++) |
题目地址:力扣这道题的意思就是会取数组中的某个位置,将其与之后的部分放到数组头部,而数组头部的部分放在这个位置之后。由于数组之前是保证有序的,因此整个数组除了那一个位置会出现非升序的情况,其他位置都是有序的。题目要求查找元素的时间复杂度是O(logn),再加上数组有序,因此可以确定这道题考察的就是二分查找的变形情况。 原先的二分查找,如果目标数小于mid,那么就往左找;目标数大于mid,就往右找。而这里的情况发生了改变,因为可能存在某个位置失序的可能。我们可以列出一个例子试试,如下所示比如在nums_1中我们需要寻找0,若按照之前的二分方法,我们可能就往左边一直找,发现没有最后返回-1。因此这道题目的关键就在于找到原来数组的头到底是位于mid的左边还是右边,来判断我们应该向哪边查找。
我们可以发现,在所有可能的情况里,mid位置的元素和right位置的元素只有两种可能性,分别是mid位置元素 > right位置元素,?mid位置元素 <?right位置元素,由于题目保证了数组中没有相同元素,因此第一次二分查找不可能出现等于的情况。 我们可以观察到一个现象: 1、当mid位置元素 > right位置元素时(说明原数组的头在mid位置右边),mid元素及其左边是严格升序的,这意味着唯一可能出现失序的情况在mid右边 2、mid位置元素 <?right位置元素时(说明原数组的头在mid位置或其左边),mid元素及其右边是严格升序的,这意味着唯一可能出现失序的情况在mid左边 因此,根据上面观察到的现象,我们就可以在二分查找的时候确定到底应该是往左边找还是往右边找了。 解法1:二分查找
解法2:二分查找(极简)这里是根据力扣上一位大佬的思路,我自己再做整理得出的思路总结。首先这道题之所以麻烦,之所以不能直接套用二分查找,归根结底其原因就是因为可能存在某点失序的情况,因此下一轮循环到底是向左还是向右就不好判断,所以我们只要明确了下一轮往左或往右的条件,就能写出简洁优雅的代码。根据题意,我们可以归类成以下两种情况。 这里我们考虑往左搜索的情况。左图是一种情况,也就是反转的位置在mid之后;右图是第二种情况,反转的位置在mid之前。其实还有第三种情况,就是反转的位置正好在mid,这种情况和第一种情况的处理方式其实是一样的。但是由于反转的位置我们不知道,所以讨论反转位置不好作为条件。而观察例子可以发现,我们其实可以用数组最左边的元素和中间元素的关系来判断当前子区间是否包含反转的部分。我们可以看下图:
综上所述,满足下列三个条件中任一就往左搜索: 1. 2. 3. 我们仔细观察可以发现这上面三个条件可以用下面三部分来体现,分别是target和mid的关系,0和target的关系,mid和0的关系。 1、 2、? 3、 由此,因为上面三个条件是把所有的可能性都考虑到了,因此上面的三部分最多只会同时成立两个,或者同时不成立两个,不可能出现三个都成立或者三个都不成立的情况。于是我们可以通过异或运算符来捕捉两个同时为真和两个都不为真(只有一个为真)的情况。 对这三部分做异或,若三项均为真或一个为真,异或结果为真,此时向右搜索。这样我们就得到了是否应该向右的判断条件。其它情况就应该向左搜索,但是我们要注意到的情况,若出现这种情况,三部分均为假,此时应该向左,因此我们在向左的时候就不要把right设置为mid-1,而是直接设置为mid,防止这种情况被忽略。 代码如下:
Accepted
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 21:20:14- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |