当前位置: 首页 > news >正文

二分查找旋转数组

已知整数数组nums,先按升序排序后,再旋转。旋转k位后,元素分别为nums[k],nums[k+1]...nums[0]...nums[k-1]。请查找target 是否存在,如果存在返回所在索引;否则返回-1。假定nums没有重复的元素。

假定排序后的数组为{1,2,3,4,5}。

旋转0位:不变。

旋转1位:{2,3,4,5,1}

旋转2位:{3,4,5,1,2}

旋转3位:{4,5,1,2,3}

旋转4位:{5,1,2,3,4}

解题思路

观察后,可以得到如下结论:

旋转数组,可以拆分成左右两个升序数组,且左数组的任意元素都大于右数组的任意元素。

分两步:

  • 找到数组的分界线RBegin,[0,RBegin)是左数组,[RBegin,n)是右数组。特殊情况:只有一个升序数组,则RBegin为0,左数组为空。
  • 如果是小于等于nums.back(),在右边找;否则在左边找。升序寻找元素之前已经讲过了,就不累赘了。
            1. 寻找RBegin

nums[mid] < nums.back()

扔掉右边,不扔mid

nums[mid] == nums.back()

扔掉右边,不扔mid

nums[mid] > nums.back()

扔掉左边,扔掉mid

故用左开右闭空间。

代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int rBegin = FindRBegin(nums);
        if (target <= nums.back())
        {
            return Find(nums, rBegin, nums.size(), target);
        }
        return Find(nums, 0, rBegin, target);
    }
    int FindRBegin(const vector<int>& nums)
    {
        int left = -1, r = nums.size()-1;//左开右闭
        while (r - left > 1)
        {
            const int mid = left + (r - left) / 2;
            if (nums[mid] <= nums.back())
            {
                r = mid;
            }
            else
            {
                left = mid;
            }
        }
        return r;
    }
    int Find(const vector<int>& nums, int left, int r, int target)
    {
        while (r - left > 1)
        {
            const auto mid = left + (r - left) / 2;
            if (nums[mid] <= target)
            {
                left = mid;
            }
            else
            {
                r = mid;
            }
        }
        return (target == nums[left]) ? left : -1;
    }
};
int main()
{
    vector<int> vNums = {1,2,3,4,6};
    auto res = Solution().search(vNums, 4);
    std::cout << "index:" <<  res;
    if (-1 != res)
    {
        std::cout << " value:" << vNums[res];
    }
}

注意

开发及测试操作系统:Windows10(安装的时候没注意,安装成了英文版)
开发及测试环境:Microsoft Visual Studio 2022  
如果还不明白,请看我的视频;如果看完视频,还是不明白,请下载源码后,直接修改。
 

http://www.lryc.cn/news/132257.html

相关文章:

  • 关于3D位姿旋转
  • 解锁项目成功的关键:项目经理的结构化思维之道
  • 力扣974被K整除的子数组
  • 简单认识Docker数据管理
  • UDP数据报结构分析(面试重点)
  • 【Java 动态数据统计图】动态数据统计思路案例(动态,排序,数组)二(113)
  • C++进阶 类型转换
  • Idea中隐藏指定文件或指定类型文件
  • 第2步---MySQL卸载和图形化工具展示
  • 原型和原型链
  • 解决ios隔空播放音频到macos没有声音的问题
  • LTPP在线开发平台【使用教程】
  • 0818 新增码表 git拉取代码
  • AI 绘画Stable Diffusion 研究(十)sd图生图功能详解-精美二维码的制作
  • C# File.ReadAllLines()报错
  • LeetCode 1162. As Far from Land as Possible【多源BFS】中等
  • 【算法】二分查找(整数二分和浮点数二分)
  • git压缩/合并多次commit提交为1次commit提交
  • 【3519DV500】AI算法承载硬件平台_2.5T算力+AI ISP图像处理_超感光视频硬件方案开发
  • Linux系统基础服务启动的方法
  • STM32 FLASH 读写数据
  • excel功能区(ribbonx)编程笔记--1 初识功能区
  • 电脑远程接入软件可以进行文件传输吗?快解析内网穿透
  • react-native-webview使用postMessage后H5不能监听问题(iOS和安卓的兼容问题)
  • 通过LD_PRELOAD绕过disable_functions
  • Python批量爬虫下载文件——把Excel中的超链接快速变成网址
  • Crimson:高性能,高扩展的新一代 Ceph OSD
  • 【websocket】websocket-client 与 websockets
  • Qt快速学习(一)--对象,信号和槽
  • Qt6之如何为QDialog添加最大化和最小化按钮