跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

搜索旋转排序数组:二分查找 C++ 解法

介绍如何在旋转排序数组中搜索目标值。给定一个升序排列且互不相同的整数数组,该数组在未知下标处进行了旋转。要求设计时间复杂度为 O(log n) 的算法找到目标值的下标,若不存在则返回 -1。核心思路是利用二分查找,每次将搜索区间分为两部分,判断哪一部分是有序的,并根据目标值与边界值的关系决定搜索方向。代码使用 C++ 实现,包含详细的调试示例。

Kubernet发布于 2026/3/30更新于 2026/9/1165 浏览
搜索旋转排序数组:二分查找 C++ 解法

题目描述

整数数组 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 -10^4 <= nums[i] <= 10^4 nums 中的每个值都 独一无二 题目数据保证 nums 在预先未知的某个下标上进行了旋转 -10^4 <= target <= 10^4

题解

解题思路

思路一(二分查找):
  1. 因数组是通过旋转得到,所以存在两个升序部分(也可能只存在一个)。我们采用二分查找的方法,查找到 mid 中间坐标,此时 mid 左右两侧必定是一侧有序,一侧无序(左侧包含 mid,右侧区间包含 mid)(有序也可看做无序处理)。
  2. 首先判断 nums[mid] 是否等于 target,若相等则直接返回。
  3. 若 nums[mid] != target。可通过 nums[mid] 与 nums[left] 的比较,来判断左侧区域是否有序。
    • nums[mid] >= nums[left](注意这里是>=,当存在两个元素时 left = mid。如 [1,2],target=2)左侧有序,右侧无序,则需判断 target 是否在 nums[left]~nums[mid] 的区间内。
      • 若 target 在区间内,则在左区间(有序区间)继续进行查找(此时为普通的二分查找):right = mid-1
      • 若 target 不在区间内,则在右区间(无序区间)继续进行查找:left = mid+1
    • nums[mid] <= nums[right] 左侧无序,右侧有序,则需判断 target 是否在 nums[mid]~nums[right] 的区间内。
      • 若 target 在区间内,则在右区间(有序区间)继续进行查找(此时为普通的二分查找):left = mid+1
      • 若 target 不在区间内,则在左区间(无序区间)继续进行查找:right = mid-1
  4. 若 left > right 则查找失败。

例:nums={4,5,6,7,0,1,2};target=0; 初始:left = 0, right = 6, target = 0,中间元素 nums[mid] = 7,不等于目标值,左侧有序,target 不在左侧区间,更新 left = 4。 第二次:left = 4, right = 6,中间元素 nums[mid] = 1,不等于目标值,左侧有序,target 在左侧区间,更新 right = 4。 第三次:left = 4, right = 4,中间元素 nums[mid] = 0,等于目标值,返回索引 4。

  1. 复杂度分析:
    • 时间复杂度:O(logn),其中 n 为 nums 数组的大小。整个算法时间复杂度即为二分查找的时间复杂度 O(logn)。
    • 空间复杂度:O(1)。

代码实现

代码实现(思路一(二分查找)):
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        int mid;
        while (left <= right) {
            // 计算中间元素的下标
            mid = left + (right - left) / 2;
            // 如果中间元素为目标值 target 则返回中间元素的下标
            if (nums[mid] == target) return mid;
            // 判断左侧区间是否有序
            if (nums[left] <= nums[mid]) {
                // 若左侧有序,则判断 target 是否存在左侧区间范围内,存在则查找左侧区间,否则查找右侧区间
                if (nums[left] <= target && target < nums[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            } else {
                // 若右侧区间有序,则判断 target 是否存在右侧区间范围内,存在则查找右侧区间,否则查找左侧区间
                if (nums[mid] < target && target <= nums[right]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
        }
        // 如果查找不到 target 则返回 -1
        return -1;
    }
};

调试示例

#include<iostream>
#include<vector>
using namespace std;

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        int mid;
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (nums[mid] == target) return mid;
            if (nums[left] <= nums[mid]) {
                if (nums[left] <= target && target < nums[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            } else {
                if (nums[mid] < target && target <= nums[right]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
        }
        return -1;
    }
};

int main(int argc, char const* argv[]) {
    vector<int> nums = {4,5,6,7,0,1,2};
    int target = 0;
    // 旋转排序数组
    Solution s;
    cout << s.search(nums, target);
    return 0;
}

目录

  1. 题目描述
  2. 输入输出样例
  3. 题解
  4. 解题思路
  5. 思路一(二分查找):
  6. 代码实现
  7. 代码实现(思路一(二分查找)):
  8. 调试示例

更多推荐文章

查看全部
  • Git 核心概念解析:从版本控制到团队协作实战
  • 使用 Web Scraper 插件爬取知乎评论数据
  • MySQL 数据库基础入门总结
  • Sora2 API 使用与调用实践及前端接入示例
  • GitHub Copilot 实战:Python 开发中的 AI 辅助技巧
  • 富文本编辑集成指南:5 阶段实现低代码高效开发
  • 基于 OpenClaw 搭建 QQ AI 办公机器人:关键词触发与邮件发送
  • 消息队列选型:Kafka、RabbitMQ 与 Redis 对比分析
  • Qwen3Guard-Gen-WEB 企业级部署与权限控制指南
  • llama.cpp Docker 镜像国内加速下载方法
  • 基于 AI 快速开发 MCP 服务插件并实现本地与线上部署
  • Qwen3+Qwen Agent 智能体开发实战:接入 MCP 工具
  • AI 数据标注工具实战:提速 3 倍的经验总结
  • AI Agent 框架选型:OpenClaw、LangChain、AutoGPT、CrewAI 深度对比
  • AI 时代生产力变革:非技术背景如何快速构建应用
  • Docker 部署 AI 量化分析平台及波浪理论实战
  • 华为 OD 机试双机位 C 卷 - 叠积木
  • 基于 Higress 将 REST API 转换为 MCP Server 实战指南
  • Claude Code 深度解析:Anthropic 终端 AI 编程助手实战指南
  • 鸿蒙 HarmonyOS 6 混合开发:ArkWeb 加载机制与 Cookie 管理

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online