首页 > 其他分享 >搜索旋转排序数组---二分查找

搜索旋转排序数组---二分查找

时间:2023-02-26 11:33:29浏览次数:51  
标签:二分 分界点 target nums int mid --- 查找

搜索旋转排序数组

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:

输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:

输入:nums = [1], target = 0
输出:-1

提示:

1 <= nums.length <= 5000
-104 <= nums[i] <= 104
nums 中的每个值都 独一无二
题目数据保证 nums 在预先未知的某个下标上进行了旋转
-104 <= target <= 104

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/search-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

题目要求O(logn)的时间复杂度,也就是遍历都不行。由于是两个部分分别有序,我的想法是先二分查找到分界点再在两个区间上分别二分查找。找分界点是可以二分的,因为区间是按照某种性质划分为两个部分,分界点的性质是nums[n] > nums[n-1] && nums[n] > nums[n+1]也就是最大值,同时通过与nums[0]大小进行比较判断左右。写的时候发现不太会写查找点的性质,后来按照区间划分的方法写。将数组划分为>= nums[0]和<nums[0],查找>=nums[0]的右端点即可。找到分界点再写二分就简单了。

code

class Solution {
public:
    //两个部分分别有序
    //O(logn)
    //能不能先logn找到分界点再分别logn查找呢
    //是可以的,有明显的分界点,二分可以找到分界点
    //分界点n的性质:nums[n-1] > nums[n] > nums[n + 1]也就是最大值
    //如果落在两侧如何区分左右呢?大小

    //按照区间划分的方法:左侧区间nums[n] < nums[n+1] && >= nums[0] 右侧区间nums[n] < nums[n+1] && < nums[0]
    //不需要按照分界点n的性质查找,按照区间划分来查找端点即可,需要查找到的是>=nums[0]的右端点
    //这样便可以查找到最大值同时在有序的情况下也是可以查找到最大值

    int search(vector<int>& nums, int target) {
        
        int l = 0,r = nums.size() -1;

        while(l < r)
        {
            int mid = (l + r + 1) / 2;
            if(nums[mid] >= nums[0]) l = mid;
            else r = mid -1;
        }
    
        int i = 0,j = l;
        while(i < j)
        {
            int mid = (i + j + 1) / 2;
            if(nums[mid] <= target) i = mid;
            else j = mid - 1;
        }
        
        if(nums[i] == target) return i;

        i = l + 1,j = nums.size() - 1;
        while(i < j)
        {
            int mid = (i + j + 1) / 2;
            if(nums[mid] <= target) i = mid;
            else j = mid - 1;
        }

        if(i < nums.size() && nums[i] == target) return i;
        else return -1;
    
    }
};

标签:二分,分界点,target,nums,int,mid,---,查找
From: https://www.cnblogs.com/huangxk23/p/17156354.html

相关文章

  • Jumps,cf1455b,VJ-HZNUFeb1
    (仅做为个人笔记,反思)题目意思:开始在原点,返回到达x位置的操作数操作:1.在第k轮时走到+k位置(y+k)2.走-1位置(y-1)思路:先一直选择操作1,直到y>=x。1.若等于......
  • C程序集成Backward-cpp使用示例
    原文地址:https://www.cnblogs.com/liqinglucky/p/backward-in-C.html在文章Backward-cpp:Segmentationfault时打印backtrace中已经介绍了backward-cpp的编译安装。不过......
  • 考研算法辅导课笔记:第十七讲--枚举和位运算
    这节课主要讲枚举,位运算成员函数booloperator<(constRange&b)const{};括号中的const表示参数b对象不会被修改;在函数末尾加CONST这样的函数叫常成员函数。常成员函......
  • OpenSSL 介绍(4)--非对称加密
    本文主要介绍如何使用OpenSSL来进行非对称加解密,使用的算法为RSA,DSA算法的使用方法类似;文中所使用到的软件版本:OpenSSL1.1.1s、CentOS 7.9.2009。1、非对称加密算法......
  • CDC设计实例-02
    CDC设计实例加速器假设要处理一项业务比如图像处理,有两种方向,第一种选择一些通用的处理器CPU\GPU\DSP等通用的处理器,第二种是将算法映射成IP,直接使用IP进行处理图像处理......
  • ECharts笔记--实现地图版的数据显示(存在bug/┭┮﹏┭┮/)
    相关描述前几天实现了柱状图等图的数据可视化,现在就来接着实现一下“更加”形象的数据可视化吧!具体实现如下<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/......
  • NEMU PA 3-3 实验报告
    一、实验目的在上一章PA3-2中,我们实现了分段机制,将48位的虚拟地址vaddr转换成了laddr。为什么不是paddr呢?这就要说到这一章要完成的东西:**分页机制**。从80386开始,计算......
  • springboot3.0整合GraalVM-Native-Support,打包本地exe(native-image)。添加native-maven
    0.【idea新建一个springbootdemo项目】勾选GraalVMNativeSupport。其它略(太基础了)1.【环境准备】安装GraalVM、VisualStudio、NativeImage​​https://gitee.com/lishu......
  • WARN tool.BaseSqoopTool: Setting your password on the command-line is insecure解
    sqoop执行命令[root@kynode3server]#sqooplist-databases--connectjdbc:mysql://kynode1:3306--usernameroot--password1234562023-02-1911:18:40,514INFOsqoop......
  • HTML--字体
    <!docpytehtml><html><head><title>字体</title></head><style>.fonth1{font-family:"楷体";}.fonth3{font-wiight:30px;font-heigh:30px;......