当前位置: 首页 > 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.lryc.cn/news/598091.html

相关文章:

  • 【STM32】FreeRTOS 任务的删除(三)
  • 力扣面试150题--在排序数组中查找元素的第一个和最后一个位置
  • C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(三)
  • MapStruct类型转换接口未自动注入到spring容器中
  • 点击按钮滚动到底功能vue的v-on:scroll运用
  • 大模型微调学习笔记(基于讯飞星辰MaaS速学版)
  • Hive常用函数
  • CSDN技术专栏开篇:高效开发环境搭建指南
  • 重构数据库未来:金仓数据库,抢占 AI 原生时代先机
  • 基础NLP | 01 机器学习 深度学习基础介绍
  • uni-appDay02
  • uniapp中flex布局gap属性兼容处理
  • LockPatternUtils中比较重要的方法
  • day46.通道注意力
  • 【SpringAI实战】FunctionCalling实现企业级自定义智能客服
  • Quarkus利用 MicroProfile 实现微服务特性
  • 基于深度学习的图像分类:使用EfficientNet实现高效分类
  • 期货交易系统:市场生态中的功能映射与价值逻辑
  • uni-app小程序云效持续集成
  • Etcd原理基础学习
  • Java 垃圾回收器之CMS GC问题分析与解决
  • 二分查找----5.寻找旋转排序数组中的最小值
  • fabric搭建基础的测试网络
  • ARM 学习笔记(四)
  • 若依框架在 IDEA 中运行的前置软件环境配置指南
  • AI开放课堂:钉钉MCP开发实战
  • 4种灵活的方法从POCO手机中删除联系人
  • 移动管家手机控车便捷性如何
  • 数据库集群环境漏洞修复
  • uniapp写app做测试手机通知栏展示内容