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

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

题目链接

/**

        升序数组在某个位置被分割为前后两部分,前后两部分整体互换;在被改变后的数组中找到目标值

        O(log n)---> 二分查找

        特点:

            旋转后的数组被分割为两个独立的递增区间

            左半区的最小值,大于右半区的最大值(mid所在区间的判断依据)

        二分策略:

            首先判断mid落在左区间还是右区间,其次判断target是否在端点到mid之间

            若target是在端点到mid之间,则可以确定target所在的半区,此时进行常规二分即可

            若target不在端点到mid之间,则无法具体确定其是在mid所在半区的剩余部分,还是另一个半区

            此时迭代left或right,淘汰无效部分,重新计算mid重复上述流程,直到搜寻结束或搜寻到target为止

        判断条件细化:

            mid所在区间:

                    nums[left] <= nums[mid]---> mid必定在左半区,反之在右半区; 依据:左半区的最小值,大于右半区的最大值

            target所在区间:

                    若mid在左半区:nums[left] < target && target < nums[mid]--->target与mid同在左半区,继续常规二分即可

                    若mid在右半区:nums[mid] < target && target < nums[right]--->target与mid同在右半区,继续常规二分即可

                    若表达式不成立,则无法确定target所在半区,则淘汰无效部分重新判断

            注意事项:

                    由于未真正找到数组两半区如何划分,当target所在分区确定后,原本判断target所处独立分区的代码功能会退化为常规二分,稍显冗余无法避免

*/

class Solution {/**升序数组在某个位置被分割为前后两部分,前后两部分整体互换;在被改变后的数组中找到目标值O(log n)---> 二分查找特点:旋转后的数组被分割为两个独立的递增区间左半区的最小值,大于右半区的最大值(mid所在区间的判断依据)二分策略:首先判断mid落在左区间还是右区间,其次判断target是否在端点到mid之间若target是在端点到mid之间,则可以确定target所在的半区,此时进行常规二分即可若target不在端点到mid之间,则无法具体确定其是在mid所在半区的剩余部分,还是另一个半区此时迭代left或right,淘汰无效部分,重新计算mid重复上述流程,直到搜寻结束或搜寻到target为止判断条件细化:mid所在区间:nums[left] <= nums[mid]---> mid必定在左半区,反之在右半区; 依据:左半区的最小值,大于右半区的最大值target所在区间:若mid在左半区:nums[left] < target && target < nums[mid]--->target与mid同在左半区,继续常规二分即可若mid在右半区:nums[mid] < target && target < nums[right]--->target与mid同在右半区,继续常规二分即可若表达式不成立,则无法确定target所在半区,则淘汰无效部分重新判断注意事项:由于未真正找到数组两半区如何划分,当target所在分区确定后,原本判断target所处独立分区的代码功能会退化为常规二分,稍显冗余无法避免*/public int search(int[] nums, int target) {//双指针置于有效部分两端int left = 0, right = nums.length - 1;while(left <= right) {int mid = (left + right) >>> 1;//找到目标值if(target == nums[mid]) {return mid;}//判断mid所在区间if(nums[left] <= nums[mid]) { //mid在左半区//判断target所在区间if(nums[left] <= target && target < nums[mid]) { //target必定在左半区right = mid - 1; //淘汰无效部分,后续为常规二分} else { //无法确定target所在半区left = mid + 1; //淘汰无效部分,重新判断(不在 left -> mid之间)}} else { //mid在右半区if(nums[mid] < target && target <= nums[right]) { //target必定在右半区left = mid + 1; //淘汰无效部分,后续为常规二分} else { //无法确定target所在分区right = mid - 1; //淘汰无效部分,重新判断(不在 mid -> right之间)}}}return -1;}
}

http://www.dtcms.com/a/295680.html

相关文章:

  • 为什么Java的String不可变?
  • 洛谷P1512 伊甸园日历游戏
  • Qt(资源库和按钮组)
  • Django基础(八)———数据库外键及表关系
  • DRF - 博客列表API
  • GaussDB 数据库架构师(八) 等待事件概述-1
  • Spring Boot项目的模块继承父项目的全部依赖
  • 中国5G RedCap基站开通情况及2025年全年计划
  • 【ComfyUI学习笔记03】案例学习:图片放大的3个基本工作流
  • 基于规则架构风格对业务的重构
  • 与deepseek的问答:dot net与Borland VCL的关系
  • 抖音小游戏好做吗?
  • MySQL的底层原理--InnoDB记录存储结构
  • 【Unity开发】飞机大战项目实现总结
  • Unity GC 系列教程第四篇:GC Alloc 优化技巧与实践(下)与 GC 调优
  • DBA常用数据库查询语句(2)
  • 【学习路线】JavaScript全栈开发攻略:前端到后端的完整征程
  • Redis数据库入门教程
  • Windchill用SQL获取所有组织下的所有用户
  • C++11之可变参数模板
  • ac日志报ARP-neighbor-failed问题定位过程
  • langchain+本地embedding模型+milvus实现RAG
  • ChatGPT Agent架构深度解析:OpenAI如何构建统一智能体系统
  • 青少年编程学习的新选择——《CCF GESP 直通车》与《GESP 编程能力等级认证一本通》深度剖析
  • 根据字符串数组的顺序重新排序 List顺序
  • 中国历史朝代顺序以及朝代歌
  • 核心数据结构:DataFrame
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-18,(知识点:传输线阻抗匹配方式)
  • OpenAI最新大模型GPT-4o体验之Code Copilot AI编程大模型
  • 电子书转PDF格式教程,实现epub转PDF步骤