【算法训练-数组 五】【二分查找】:旋转数组的最小数字、旋转数组的指定数字

news2025/1/11 9:00:19

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【数组的二分查找】,使用【数组】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。

在这里插入图片描述

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

旋转数组的最小数字【MID】

先来找最小值

题干

直接粘题干和用例
在这里插入图片描述

解题思路

通过题目描述我们知道,旋转点后的排序子区间最大值也比旋转点之前的排序子区间最小值小,最小值就是旋转点,也就是数组的中间部分,所以我们使用碰撞双指针从两边向中心搜索,不断缩小搜索范围:

  • step 1:双指针指向旋转后数组的首尾,作为区间端点。
  • step 2:若是区间中点值大于区间右界值,说明中点在左侧递增区间,则最小的数字一定在中点右边
  • step 3:若是区间中点值等于区间右界值,则是不容易分辨最小数字在哪半个区间,比如[1,1,1,0,1],应该逐个缩减右界
  • step 4:若是区间中点值小于区间右界值,说明中点在右侧递增区间,则最小的数字一定在中点左边
  • step 5:通过调整区间最后即可锁定最小值所在。

代码实现

给出代码实现基本档案

基本数据结构数组
辅助数据结构
算法二分查找
技巧双指针(碰撞双指针)

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型
     */
    public int minNumberInRotateArray (int[] nums) {
        // 1 入参判断,参数有效性校验
        if (nums == null || nums.length == 0) {
            return -1;
        }

        // 2 定义左右碰撞指针,找中点位置
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] > nums[right]) {
                // mid在左侧递增区间,最小值在mid右侧[mid+1,right]
                left = mid + 1;

            } else if (nums[mid] < nums[right]) {
                // mid在右侧递增区间,最小值为mid或mid左侧[left,mid]
                right = mid;
            } else {
                // 无法判断,缩小右边界
                right--;
            }
        }

        return nums[left];
    }
}

复杂度分析

时间复杂度:O(log n),二分法最坏情况对n取2的对数
空间复杂度:O(1),常数级变量,无额外辅助空间

搜索旋转排序数组【MID】

OK,接下来难度升级,不找最小值,找的是指定值

题干

直接粘题干和用例
在这里插入图片描述

解题思路

给出解题思路,最好有图对于有序数组,可以使用二分查找的方法查找元素。但是这道题中,数组本身不是有序的,进行旋转后只保证了数组的局部是有序的,这还能进行二分查找吗?答案是可以的。

可以发现的是,我们将数组从中间分开成左右两部分的时候,一定有一部分的数组是有序的。拿示例来看,我们从 6 这个位置分开以后数组变成了 [4, 5, 6] 和 [7, 0, 1, 2] 两个部分,其中左边 [4, 5, 6] 这个部分的数组是有序的,其他也是如此。

这启示我们可以在常规二分查找的时候查看当前 mid 为分割位置分割出来的两个部分 [l, mid] 和 [mid + 1, r] 哪个部分是有序的,并根据有序的那个部分确定我们该如何改变二分查找的上下界,因为我们能够根据有序的那部分判断出 target 在不在这个部分:

  • 如果 [l, mid - 1] 是有序数组,且 target 的大小满足 [nums[l],nums[mid]),则我们应该将搜索范围缩小至 [l, mid - 1],否则在 [mid + 1, r] 中寻找。
  • 如果 [mid, r] 是有序数组,且 target 的大小满足 (nums[mid+1],nums[r]],则我们应该将搜索范围缩小至 [mid + 1, r],否则在 [l, mid - 1] 中寻找。

在这里插入图片描述

  • 定理一:只有在顺序区间内才可以通过区间两端的数值判断target是否在其中
  • 定理二:判断顺序区间还是乱序区间,只需要对比 left 和 right 是否是顺序对即可,left <= right,顺序区间,否则乱序区间。
  • 定理三:每次二分都会至少存在一个顺序区间

通过不断的用Mid二分,根据定理二,将整个数组划分成顺序区间和乱序区间,然后利用定理一判断target是否在顺序区间,如果在顺序区间,下次循环就直接取顺序区间,如果不在,那么下次循环就取乱序区间。最终target一定会在一个顺序区间,即使只有它一个元素

代码实现

给出代码实现基本档案

基本数据结构数组
辅助数据结构
算法二分查找
技巧双指针(碰撞双指针)

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

class Solution {
    public int search(int[] nums, int target) {
       // 1 入参校验
        if (nums == null || nums.length == 0) {
            return -1;
        }

        // 2 定义双指针
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                return mid;
            }
            // 因为只有在有序区间内target的判断才有意义,所以每次都在有序区间内判断,并且依据目标值是否在有序区间内,移动左右指针
            if (nums[left] <= nums[mid]) {
                // 如果左边是顺序区间
                if (target >= nums[left] && target < nums[mid]) {
                    // 如果目标值在顺序区间,在顺序区间搜寻[left,mid-1]
                    right = mid - 1;
                } else {
                    // 如果目标值不在顺序区间,在非顺序区间搜寻[mid+1,right]
                    left = mid + 1;
                }
            } else {
                // 如果右边是顺序区间
                if (target > nums[mid] && target <= nums[right]) {
                    // 如果目标值在顺序区间,在顺序区间搜寻[mid+1,right]
                    left = mid + 1;
                } else {
                    // 如果目标值不在顺序区间,在非顺序区间搜寻[left,mid-1]
                    right = mid - 1;
                }
            }
        }
        return -1;
    }
}

复杂度分析

时间复杂度:O(log n),二分法最坏情况对n取2的对数
空间复杂度:O(1),常数级变量,无额外辅助空间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1002668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#,《小白学程序》第二十一课:大数(BigInteger)的四则运算之二,减法

1 文本格式 using System; using System.Linq; using System.Text; using System.Collections.Generic; /// <summary> /// 大数的&#xff08;加减乘除&#xff09;四则运算、阶乘运算 /// 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法 /// </summary> p…

GO语言网络编程(并发编程)Goroutine池

GO语言网络编程&#xff08;并发编程&#xff09;Goroutine池 1. Goroutine池 1.1.1. worker pool&#xff08;goroutine池&#xff09; 本质上是生产者消费者模型可以有效控制goroutine数量&#xff0c;防止暴涨需求&#xff1a; 计算一个数字的各个位数之和&#xff0c;例…

2.5 循环结构语句

在程序设计中&#xff0c;有时需要反复执行一段相同的代码&#xff0c;这时就需要使用循环结构来实现&#xff0c;Java语言提供了while循环、do-while循环、for循环。 一般情况下&#xff0c;一个循环结构包含四部分内容&#xff1a; 初始化部分&#xff0c;设置循环开始时变量…

正交试验设计法

正交实验设计 一、什么是正交试验设计法&#xff1f; 是一种成对测试交互的系统的统计方法。它提供了一种能对所有变量对的组合进行典型覆盖&#xff08;均匀分布&#xff09;的方法。 可以从大量的试验点中挑出适量的、有代表性的点&#xff0c;利用“正交表”&#xff0c;…

Rsync远程同步+inotify监控

一、rsync同步简介 一款快速增量备份工具 rsync&#xff08;Remote Sync&#xff0c;远程同步&#xff09; 是一个开源的快速备份工具&#xff0c;可支持本地复制&#xff0c;或者与其他SSH,rsync主机同步。 cp&#xff1a;将原文件完整的复制到指定的路径下&#xff0c;而且…

Vector底层原理——面试之我答

Vector概述 vector是STL中最常用的容器&#xff0c;vector主要功能是作动态数组来弥补传统数组的缺点&#xff0c;如&#xff1a;不灵活&#xff0c;不方便插入等等。 Vector支持随机访问&#xff0c;因此访问某一个元素的时间复杂度是O(1)。 vector中存储着许多易用的函数方法…

自动化测试入门知识 —— 数据驱动测试

一、什么是数据驱动测试&#xff1f; 数据驱动测试是一种测试方法&#xff0c;它的核心思想是通过不同的测试数据来验证同一个测试逻辑。通常情况下&#xff0c;测试用例中的输入数据和预期结果会被提取出来&#xff0c;以便可以通过不同的测试数据进行重复执行。 数据驱动测…

spacy 中文语义分析下载安装使用

概念 spaCy 下载 安装spacy pip install -U spacy -i https://pypi.tuna.tsinghua.edu.cn/simple 安装模型 https://github.com/explosion/spacy-models/releases 找到对应的模型&#xff0c;下载&#xff0c;如下图 安装 下载是gz&#xff0c;下载后安装 pip instal…

Flullter学习第一天:什么是Flullter与Flullter安装

1.简介 Flutter使用dart作为主要开发语言,开发后可多端编译,并且能调用原生api 2.安装 官网:Install | Flutter 让我们读下为中国用户特制的文档,访问中国官网 Flutter: 为所有屏幕创造精彩 - Flutter 中文开发者网站 - Flutter 获取 Flutter SDK 点击下方的安装包&#x…

记录一个iOS实现视频分片缓存拖拽快进不能播放的问题

代码现状 首先来看一下我们将视频数据塞给请求的代码 - (void)finishLoadingWithLoadingRequest:(IdiotResourceTask *)task {// printf("哈哈执行到这里执行到到这里\n");printf("哈哈哈数量数量%ld\n", self.taskList.count);//填充信息task.loadingRe…

Python/Java/Php/C#/Go/C/C++这几个主力语言,谁到底真的不行

1.前言 阿里最近又进行了史诗级的大裁员&#xff0c;IT行业肉眼可见的持续性衰退与没落。当潮水退却&#xff0c;才能看出谁在裸泳。作为当今计算机编程界的几大主力语言&#xff0c;谁才真正的裸泳者呢&#xff1f;引用原文:这几个主力语言&#xff0c;谁到底真的不行 2.描述…

Java项目-苍穹外卖-Day11-Apache ECharts数据统计

文章目录 前言Apache ECharts介绍入门案例 营业额统计需求分析代码开发功能测试 订单统计需求分析代码开发功能测试 销量排名统计需求分析代码开发功能测试 前言 主要是以下四项的统计&#xff0c;以不同形式的图形进行展示 Apache ECharts 介绍 入门案例 自己去网站上看一…

MATLAB R2018b安装教程

目录 一、软件下载 二、软件介绍 三、安装须知 四、安装步骤 【最后】 &#x1f388;个人主页&#xff1a;库库的里昂 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&#xff1a;MATLAB基础及应用&#x1f91d;希望作者的文章能…

Redis之string类型的三大编码解读

目录 string类型的三大编码 int 编码 embstr 编码 raw 编码 明明没有超过阈值,为什么变成raw&#xff1f; 查看数据类型相关命令 redis看看类型:type key 看看编码:object encoding debug结构:debug object person 在 Redis 中&#xff0c;String 类型的数据结构并…

EPICS电机支持(asynMotor)

EPICS电机支持 1&#xff09; 顶层对象是EPICS motor记录 已经对这个对象编写了很多代码&#xff1a;spec&#xff0c;IDL和Python类等 2&#xff09;下一层是EPICS设备支持 了解motor记录&#xff0c;与驱动会话 3&#xff09;最底层是EPICS驱动 对motor记录一无所知&am…

FastJson 漏洞复现

文章目录 FastJson 漏洞复现1. FastJson 1.2.24 反序列化导致任意命令执行漏洞1.1 漏洞描述1.2 漏洞原理1.3 漏洞复现1.3.1 环境启动1.3.2 漏洞检测1.3.3 漏洞验证 1.4 漏洞利用1.5 修复方案 2. Fastjson 1.2.47 远程命令执行漏洞2.1 漏洞描述2.2 漏洞复现2.2.1 环境启动2.2.2 …

SV-315C 15寸触模屏 I3工控机 网络广播主机

SV-315C 15寸触模屏 I3工控机 网络广播主机 智能公共广播系统IP网络广播主机 ※ 高档7U铝合金黑色拉丝面板&#xff0c;美观大方&#xff1b; ※ 嵌入触摸屏和数字矩阵键盘操作集成软件&#xff1b; ※ 工业级机柜式机箱设计&#xff0c;有较高的防磁、防尘、防冲击的能力…

FPGA原理与结构——时钟IP核的使用与测试

一、前言 本文介绍xilinx的时钟IP核 Clocking Wizard v6.0的具体使用与测试过程&#xff0c;在学习一个IP核的使用之前&#xff0c;首先需要对于IP核的具体参数和原理有一个基本的了解&#xff0c;具体可以参考&#xff1a; FPGA原理与结构——时钟IP核原理学习https://blog.c…

[网鼎杯 2020 青龙组]singal详细题解--VMP 直接逆向,angr模拟执行,ponce符号化

文章目录 直接逆向提取opcode获取指令执行流getflag注意 使用Angr使用Ponce插件安装并配置Ponce具体操作 参考资料 直接逆向 提取opcode 主函数并不复杂,关键内容在vm_opcode中,先提取出main函数中的opcode unsigned int OpCode[114] {0x0000000A, 0x00000004, 0x00000010,…

Spring上下文模块ApplicationContextAware

博主介绍:✌全网粉丝3W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌ 博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…