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

Leetcode 搜索旋转排序数组

在这里插入图片描述
这段代码是用于解决LeetCode第33题“搜索旋转排序数组”的Java解法。以下是对该算法思想的中文解释:

算法思想

  1. 二分查找的基本思路

    • 由于数组是部分有序的(被旋转过),我们可以利用二分查找的思想,逐步缩小搜索范围。
    • 但是与普通的二分查找不同,这里的数组被旋转过,所以需要先判断当前数组的哪个部分是有序的,再决定如何更新搜索范围。
  2. 判断有序区间

    • 通过比较nums[left]nums[mid],我们可以确定左半部分或右半部分是否是有序的。
    • 如果nums[left] <= nums[mid],说明左半部分是有序的。
    • 如果nums[left] > nums[mid],说明右半部分是有序的。
  3. 确定目标值在哪个区间

    • 如果左半部分是有序的,且目标值targetnums[left]nums[mid]之间(即nums[left] <= target < nums[mid]),那么我们将搜索范围缩小到左半部分,即更新right = mid - 1
    • 如果目标值不在左半部分,那么我们将搜索范围缩小到右半部分,即更新left = mid + 1
    • 同理,如果右半部分是有序的,且目标值targetnums[mid]nums[right]之间(即nums[mid] < target <= nums[right]),则搜索范围缩小到右半部分。
    • 否则,目标值在左半部分,因此更新right = mid - 1
  4. 返回结果

    • 如果找到目标值,则返回它的索引。
    • 如果循环结束后仍未找到目标值,则返回-1

Java 代码的逐行解释

class Solution {public int search(int[] nums, int target) {int left = 0;int right = nums.length - 1;while (left <= right) {int 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;}}}// 未找到目标值,返回-1return -1;}
}

时间复杂度

由于每次循环都会将搜索区间缩小一半,所以时间复杂度为 (O(\log n)),符合题目要求的高效查找。

总结

这个算法巧妙地利用了数组的部分有序特性,结合二分查找,在旋转数组中高效地查找目标值。

为什么如果nums[left] > nums[mid],说明右半部分是有序的。

如果nums[left] > nums[mid],说明左半区间存在旋转断点,而旋转断点之后的子数组都是有序的,所以右半部分是有序的。

nums[left] > nums[mid]时,确实可以判断左半区间存在旋转断点,这意味着左半部分并不是完全有序的。而旋转断点之后的子数组会保持有序状态,因此我们可以推断出右半部分是有序的

这也是为什么在这种情况下,我们可以安全地在右半部分进行查找,前提是目标值target在右半部分的范围内。反之,如果目标值不在右半部分的范围内,那么就去左半部分继续搜索。

你的理解完全正确!这种判断旋转数组中有序部分的方法,是解决这类问题的关键。😊

为什么这一部分代码片段if (nums[mid] < target && target <= nums[right]),如果使用判断条件if (nums[mid] <= target && target < nums[right])会得到错误的答案?

这个问题的核心在于边界条件的不同处理导致的结果差异。让我们仔细分析一下这两个条件的区别,以及为什么会得到不同的答案。

代码片段解释

if (nums[mid] < target && target <= nums[right])

条件比较

  1. 原条件if (nums[mid] < target && target <= nums[right])
  2. 错误条件if (nums[mid] <= target && target < nums[right])

原条件的含义:if (nums[mid] < target && target <= nums[right])

这个条件的意思是:

  • nums[mid] < target:目标值 target 要比 nums[mid] 大。
  • target <= nums[right]:目标值 target 小于或等于 nums[right]

该条件涵盖了目标值在右半部分有序区间内的情况,包括target等于nums[right]的情况。例如,如果右半部分的元素是[1, 2, 3, 4, 5],而target = 5,这个条件会成功匹配到5

错误条件的含义:if (nums[mid] <= target && target < nums[right])

这个条件的意思是:

  • nums[mid] <= target:目标值 target 可以等于 nums[mid]
  • target < nums[right]:目标值 target 必须严格小于 nums[right]

这个条件的一个问题是,当目标值等于nums[right]时,不会满足条件,即使target在右半部分有序区间内。例如,如果右半部分的元素是[1, 2, 3, 4, 5],而target = 5,因为5并不小于nums[right] = 5,这个条件将无法匹配到5

为什么使用错误条件会得到错误答案?

在旋转排序数组中,我们必须精确判断目标值是否在有序区间内。如果使用错误条件 if (nums[mid] <= target && target < nums[right]),就会漏掉当目标值等于右边界元素的情况,导致无法找到目标值,返回错误的结果(如返回-1)。

举个例子帮助理解

假设数组是[4, 5, 6, 7, 0, 1, 2]target = 2,那么:

  • nums[mid] 可能是0nums[right]2
  • 按照原条件 if (nums[mid] < target && target <= nums[right])
    • 0 < 2为真,2 <= 2也为真,条件成立,因此可以在右半部分继续查找。
  • 按照错误条件 if (nums[mid] <= target && target < nums[right])
    • 0 <= 2为真,但是2 < 2为假,因此条件不成立,会错误地调整查找区间。

总结

原条件 if (nums[mid] < target && target <= nums[right]) 保证了目标值即使等于右边界元素 nums[right] 时,仍然可以正确查找到。而错误条件 if (nums[mid] <= target && target < nums[right]) 会遗漏目标值等于右边界的情况,从而导致错误答案。

相关文章:

Leetcode 搜索旋转排序数组

这段代码是用于解决LeetCode第33题“搜索旋转排序数组”的Java解法。以下是对该算法思想的中文解释&#xff1a; 算法思想 二分查找的基本思路&#xff1a; 由于数组是部分有序的&#xff08;被旋转过&#xff09;&#xff0c;我们可以利用二分查找的思想&#xff0c;逐步缩小…...

Spring Task—定时任务

Spring Task 是 Spring 提供的一种轻量级定时任务调度功能&#xff0c;内置在 Spring 框架中。与 Quartz 等重量级调度框架相比&#xff0c;Spring Task 使用简便&#xff0c;无需额外依赖&#xff0c;适合在简单的调度任务场景中使用。通过注解配置方式&#xff0c;开发者可以…...

Spring Boot 应用开发概述

目录 Spring Boot 应用开发概述 Spring Boot 的核心特性 Spring Boot 的开发模式 Spring Boot 在企业应用开发中的优势 结论 Spring Boot 应用开发概述 Spring Boot 是由 Pivotal 团队开发的一个框架&#xff0c;基于 Spring 框架&#xff0c;旨在简化和加速基于 Spring …...

Chrome谷歌浏览器加载ActiveX控件之allWebDesktop控件介绍

背景 allWebDesktop控件是一款方便用户在线打开各类文档的OA办公控件。它设计比较轻巧&#xff0c;充分利用计算机程序资源打开文档&#xff0c;并将程序窗口嵌入到allWebDesktop控件区域内&#xff0c;从而实现浏览器内打开各类文档效果。 allWebPlugin中间件是一款为用户提供…...

GitHub Star 数量前 5 的开源应用程序生成器

欢迎来的 GitHub Star 数量排名系列文章的第 7 篇——最受欢迎的应用程序生成器。 之前我们已经详细探讨过&#xff1a;在 GitHub 上最受欢迎的——无代码工具、低代码项目、内部工具、CRUD项目、自部署项目和 Airtable 开源替代品。累计超过 50 个优质项目&#xff01;&#…...

DBC文件当中新建CANFD等类型的报文

同学最近有添加CANFD报文的需求&#xff0c;需要用到CANFD类型报文的DBC文件&#xff0c;这下就难住我了&#xff0c;我之前用的DBC文件只有“CAN Standard”“CAN Extended”两种类型&#xff0c;压根没见过FD的。 后来他找到了项目之前的DBC&#xff0c;打开来看&#xff0c…...

基于SpringBoot的房地产销售管理系统【附源码】

基于SpringBoot的房地产销售管理系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1用户登录功能的详细实现 4.2管理员权限的功能实现 4.2.1客户信息管理功能的详细实现 4.2.2房产管理功能的详细实现 4.2.3预约看房功能的详细实现 4.2.4论…...

圆点虚线 Android

参考 https://blog.csdn.net/l_o_s/article/details/73550876 <com.xxx.wwww.weight.PointDividerViewandroid:layout_width"match_parent"android:layout_height"wrap_content"app:PDbackgroundColor"color/white"app:dotColor"color/…...

贵州鑫宏远农业-始终致力于推动现代农业的科技创新与发展

贵州鑫宏远农业科技有限公司&#xff0c;是一家在高科技农业领域深耕细作、锐意进取的企业。自成立以来&#xff0c;我们始终致力于推动现代农业的科技创新与发展&#xff0c;业务全面覆盖农业科学研发、组织培养生产、专业育苗培植、半成品及成品精细化养护、市场销售以及全方…...

程序员做销售,从代码到客户的逆袭之路

大家好&#xff0c;我是小悟。 在这个互联网风起云涌、技术迭代日新月异的时代&#xff0c;“跨界”已然成为一种新潮流。就好似那从天而降的大侠&#xff0c;一不小心就可能横跨了数个充满奇遇与挑战的领域。 想象一下&#xff0c;一个平日里只跟代码打交道的程序员&#xf…...

Flink CDC系列之:理解学习Kubernetes模式

Flink CDC系列之&#xff1a;理解学习Kubernetes模式 准备会话模式启动会话集群设置 Flink CDC提交 Flink CDC Job Kubernetes 是一种流行的容器编排系统&#xff0c;用于自动化计算机应用程序的部署、扩展和管理。Flink 的原生 Kubernetes 集成允许您直接在正在运行的 Kuberne…...

git合并相关操作详解

在使用Git进行分支管理时,合并(merge)操作是非常常见的。下面是Git合并相关的详细步骤和一些常见的场景及注意事项。 一、 基本合并操作 假设我们有两个分支:main 和 feature,希望将 feature 合并到 main 上。 切换到目标分支 首先需要切换到你想合并到的分支。例如,切…...

前端经典【面试题】持续更新HTML、CSS、JS、VUE、FLUTTER、性能优化等

HTML/CSS 面试题 什么是语义化 HTML&#xff1f; 说明&#xff1a;语义化 HTML 使用 HTML 标签来描述内容的含义&#xff0c;而不仅仅是其外观。使用语义化标签可以提高可读性和可访问性&#xff0c;并对 SEO 友好。示例&#xff1a; <header><h1>网站标题</h1&…...

【Linux知识】linux磁盘管理深入了解

文章目录 常见磁盘管理命令行磁盘分区NASNAS 磁盘挂载&#x1f510; 如何设置NAS设备的访问权限&#xff1f; Mkfs&#x1f9d0; mkfs 命令支持哪些文件系统类型&#xff1f; Mount&#x1f511; 在Linux中&#xff0c;如何安全地卸载挂载的文件系统&#xff1f; 常见磁盘管理命…...

Qt Essential Classes

目录 QVariant QFlags QRandomGenerator 经典的Qt容器 QVector QList QMap QMultiMap QSet QHash QVariant 同std::variant是一样的&#xff0c;他是一个更加高级的union。在一个时间下&#xff0c;它虽然实际上只能是一种类型&#xff0c;但是一个variant可以hold住…...

小小猫棒onu替换家用光猫,薅运营商带宽羊毛,突破1000M

小小猫棒onu 一、总体步骤 1 记录原来光猫信息 主要包括SN&#xff0c;ploam密码&#xff0c;loid、loid密码、 mac、上网的vlan id等 一般gpon采用SN、ploam密码、SNploam密码三种中的一种认证方式 一般Epon采用loid&#xff08;逻辑id&#xff09;、mac、loid mac三种中…...

软件测试学习笔记丨Selenium学习笔记:css定位

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/22511 本文为霍格沃兹测试开发学社的学习经历分享&#xff0c;写出来分享给大家&#xff0c;希望有志同道合的小伙伴可以一起交流技术&#xff0c;一起进步~ 说明&#xff1a;本篇博客基于sel…...

python数据处理常用操作

数据处理是机器学习中非常重要的一步&#xff0c;以下是一些常用的操作和示例代码&#xff1a; 1. 数据清洗 处理缺失值&#xff1a; import pandas as pd# 读取数据 df pd.read_csv(data.csv)# 删除缺失值 df.dropna(inplaceTrue)# 用均值填充缺失值 df.fillna(df.mean(), i…...

解决minio跨域问题

MinIO 支持跨域资源共享(CORS)&#xff0c;允许你配置跨域请求的相关策略。以下是一个基本的CORS配置示例&#xff0c;你可以在MinIO的配置文件&#xff08;例如config.json&#xff09;中设置这些策略&#xff1a; 在Linux中 root/.minio 目录下如果没有就新建一个 config.jso…...

python 跳过当前循环

在 Python 中&#xff0c;可以使用 continue 语句来跳过当前循环的剩余部分&#xff0c;并继续下一次循环。continue 语句用于跳过循环体中剩余的语句&#xff0c;并立即开始下一次迭代。 以下是一个简单的示例&#xff0c;演示了如何在 for 循环中使用 continue 语句&#xf…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...