052、牛客网算法面试必刷TOP101--二分查找/排序(230503)

news2024/9/29 1:19:32

文章目录

  • 前言
  • 二分查找/排序
    • 1、BM17 二分查找-I
    • 2、BM18 二维数组中的查找
    • 3、BM19 寻找峰值
    • 4、BM20 数组中的逆序对
    • 5、BM21 旋转数组的最小数字
    • 6、BM22 比较版本号
  • 总结


前言

本文记录自己刷,牛客网的面试必刷TOP101,地址:面试必刷TOP101–二分查找.排序。题目从BM17----BM22,总共有六道题目。


提示:以下是本篇文章正文内容

二分查找/排序


1、BM17 二分查找-I

题目:

  • 请实现无重复数字的升序数组的二分查找。
  • 给定一个 元素升序的、无重复数字的整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标(下标从 0 开始),否则返回 -1。

代码实现:

public class BM17 {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param nums   int整型一维数组
     * @param target int整型
     * @return int整型
     */
    public int search(int[] nums, int target) {
        // write code here
        if (nums == null || nums.length < 1) {
            return -1;
        }
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (target == nums[mid]) {
                return mid;
            } else if (target < nums[mid]) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }
}

2、BM18 二维数组中的查找

题目:

  • 在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

代码实现:

public class BM18 {
    /**
     * @param target : 目标值
     * @param array  : 二维数组
     * @return 返回是否能在二维数组中找到目标值,true就是可以找到目标值,false则为找不到目标值
     */
    public boolean Find(int target, int[][] array) {
        if (array == null || array[0].length == 0 || target < array[0][0]) {
            return false;
        }
        int m = array.length;// 二维数组行数
        int n = array[0].length; // 二维数组的列数
        // 从左上角开始找
        int i = 0, j = n - 1;
        while (i < m && j >= 0) {
            if (target == array[i][j]) {
                return true;
            } else if (target < array[i][j]) {
                j--;
            } else {
                i++;
            }
        }
        return false;
    }
}

3、BM19 寻找峰值

题目:

  • 给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。
    • 峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于。
    • 假设 nums[-1] = nums[n] = −∞
    • 对于所有有效的 i 都有 nums[i] != nums[i + 1]
    • 可以使用O(logN)的时间复杂度实现此问题吗?

思路:

  • 好的,我又不会了,我记得是用单调性,但是我不会啊。
  • 参考视频:第十九天:寻找峰值;
  • 因为数组最左边的元素和最右边的元素都是负无穷大,所以元素维护的形状是一个山一样的,就分为两种情形:
    • 上坡:上坡就一定会走到峰顶
    • 下坡:下坡就不一定会走到峰顶
  • 并且,必须在while循环的条件中,使用小于,当出现等于就跳出循环

山谷
代码实现:

public class BM19 {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param nums int整型一维数组
     * @return int整型
     */
    public int findPeakElement(int[] nums) {
        // write code here
        int left = 0, right = nums.length - 1;
        int mid = 0;
        //
        while (left < right) {
            mid = left + (right - left) / 2;
            if (nums[mid] < nums[mid + 1]) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return right;
    }
}

4、BM20 数组中的逆序对

题目:

  • 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
  • 输入一个数组,求出这个数组中的逆序对的总数P。
  • 并将P对1000000007取模的结果输出。 即输出P mod 1000000007。
  • 要求:空间复杂度 O(n),时间复杂度 O(nlogn)。

思路:

  • 我还是不会,无语。
  • 参考视频:小米,shopee都让现场手撕了 | 51. 数组中的逆序对。
  • 根据时间复杂度,就可以想到使用归并排序;
  • 在最后将两个有序数组进行归并的时候,记录逆序对的个数;

代码实现:

public class BM20 {
    // 数组逆序对
    public int InversePairs(int[] array) {
        // 使用归并排序,记录逆序对
        mergeSort(array, 0, array.length - 1);
        return count;
    }

    int count = 0;

    public void mergeSort(int[] arr, int left, int right) {
        if (left < right) {
            int mid = left + (right - left) / 2;
            mergeSort(arr, left, mid);
            mergeSort(arr, mid + 1, right);
            merge(arr, left, mid, right);
        }
    }

    void merge(int[] arr, int left, int mid, int right) {
        int[] help = new int[right - left + 1];
        int index = 0;

        int i = left, j = mid + 1;
        while (i <= mid && j <= right) {
            if (arr[i] <= arr[j]) {
                help[index++] = arr[i++];
            } else {
                count += mid - i + 1;
                count %= 1000000007;
                help[index++] = arr[j++];
            }
        }
        while (i <= mid) {
            help[index++] = arr[i++];
        }
        while (j <= right) {
            help[index++] = arr[j++];
        }
        for (index = 0; index <= right - left; index++) {
            arr[left + index] = help[index];
        }
    }
    
}

5、BM21 旋转数组的最小数字

题目:

  • 有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。
  • 请问,给定这样一个旋转数组,求数组中的最小值。

思路:

  • 对于这种旋转数组,最重要的就是找到旋转点;
  • 二分取中间的值,和两端进行比较,比较后缩小区间范围。

代码实现:

public class BM21 {
    public int minNumberInRotateArray(int[] array) {
        int left = 0, right = array.length - 1;

        while (left < right) {
            int mid = left + (right - left) / 2;

            if (array[mid] > array[right]) {
                left = mid + 1;
            } else if (array[mid] < array[right]) {
                right = mid;
            } else {
                right--;
            }
        }

        return array[right];
    }
}

6、BM22 比较版本号

题目:

  • 牛客项目发布项目版本时会有版本号,比如1.02.11,2.14.4等等。
  • 现在给你2个版本号version1和version2,请你比较他们的大小
  • 版本号是由修订号组成,修订号与修订号之间由一个"."连接。1个修订号可能有多位数字组成,修订号可能包含前导0,且是合法的。例如,1.02.11,0.1,0.2都是合法的版本号
  • 每个版本号至少包含1个修订号。
  • 修订号从左到右编号,下标从0开始,最左边的修订号下标为0,下一个修订号下标为1,以此类推。
  • 比较规则:
    • 一. 比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较忽略任何前导零后的整数值。比如"0.1"和"0.01"的版本号是相等的
    • 二. 如果版本号没有指定某个下标处的修订号,则该修订号视为0。例如,“1.1"的版本号小于"1.1.1”。因为"1.1"的版本号相当于"1.1.0",第3位修订号的下标为0,小于1
    • 三. version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0.

思路:

  • 这道题居然都需要想,真无语啊我。
  • 将字符串划分为数组,比较大小。

代码实现:

public class BM22 {
    /**
     * @param version1 : 版本号一
     * @param version2 : 版本号二
     * @return version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0.
     */
    public int compare(String version1, String version2) {
        // write code here
        // 分割版本号
        String[] v1 = version1.split("\\.");
        String[] v2 = version2.split("\\.");

        for (int i = 0; i < v1.length || i < v2.length; i++) {
            int x = i < v1.length ? Integer.valueOf(v1[i]) : 0;
            int y = i < v2.length ? Integer.valueOf(v2[i]) : 0;
            if (x < y) {
                return -1;
            } else if (x > y) {
                return 1;
            }
        }
        return 0;
    }
}

总结

  1. 升序数组的二分查找,注意边界问题;
  2. 二维数组中的查找,也是关于指针的使用;
  3. 寻找峰值,是将峰值看成山顶,上坡下坡问题;
  4. 数组中的逆序对,归并排序;
  5. 旋转数组的最小数字,可以想象成上山下山的问题,找到那个转折点;
  6. 比较版本号,切割成数组后比较。

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

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

相关文章

【GAMES101】05 Rasterization(Triangles)

光栅化过程&#xff1a;将一系列变换后的三角形转换为像素的过程。 三角形在图形学中得到很多的应用。 最基础的多边形&#xff08;边数最少&#xff09;。任何多边形都可以拆成三角形。性质&#xff1a;三角形内部一定是平面的。三角形内外部定义非常清楚。定义三个顶点后&a…

libfacedetection 人脸检测库 检测速度慢的问题

目录 一、libfacedetection 性能介绍 英特尔CPU 使用AVX2指令集 使用AVX512指令集 嵌入式设备 二、加速检测速度 libfacedetetion的前向推理速度很快的原因 使用axv2加速指令 一、libfacedetection 性能介绍 在上一篇文章中&#xff0c;我发现使用摄像头检测&#xff0c;构…

C++入门——内联函数的介绍

目录 前言 内联函数 1. 概念 2.特性 前言 今天小编给大家带来的是内联函数的介绍&#xff0c;大家可能之前没有听过内联函数这个名词&#xff0c;那么今天就和小编一起认识一下这个朋友吧。 内联函数 我们每次在调用函数时都会开辟一个函数栈帧&#xff0c;那么过度的函数…

上海联影面试(部分)(未完全解析)

一面 Spring Boot为什么可以自启动&#xff0c;且变成一个web项目&#xff1f;本地连不上网&#xff0c;Maven缺一个jar包&#xff0c;怎么解决&#xff1f;linux用什么命令找到占用指定端口的进程&#xff0c;并杀掉&#xff1f;Answer by new bing: 查找被占用端口的PID&am…

单载波传输与多载波传输

一、单载波传输 1. 单载波基带传输&#xff1a;系统模型 信道h(t)的带宽为W T&#xff1a;符号周期&#xff0c;数据速率&#xff1a;R1/T&#xff0c;每秒传输R个符号&#xff0c;单位&#xff1a;Hz z(t)&#xff1a;加性噪声 g(t)带宽有限&#xff0c;时间无限&#xff0c…

AI 图像生成工具可以取代摄影师吗?让我们从原理开始聊聊

AI 的风已经吹向了每一个人&#xff0c;在这篇文章中我们一起来聊一聊 AI 图像生成的原理以及未来。 作为一个非职业的摄影爱好者&#xff0c;我通常会在 Instagram 上面搜罗各种各样的优质图片并将其放进我的收藏夹。其中&#xff0c;有一位我关注了很久的德国摄影师&#xff…

Linux常用快捷键

前言&#xff1a;由于需要&#xff0c;梳理了一下常用的快捷键&#xff0c;以便忘记时查找。 Linux系统快捷键&#xff1a;(Bash解释器) 1&#xff09;Tab键 补齐命令补齐路径显示当前目录下的所有目录 2&#xff09;清屏&#xff1a; clearCtrl L ( “L” 大小写均可 ) …

Cadence基础操作:ADE L仿真基础操作

仿真器启动 schematic视图左上角 launch 启动各种仿真器&#xff0c;ADE L界面左上角Launch 启动ADL XL 和ADE GXL。通过ADE L启动的ADEXL 会继承ADE L的各种设置&#xff0c;如变量、plot and save的点等等。 仿真器主要设置 1.仿真器选择&#xff1a;如图&#xff0c;Setup里…

Linux进程初识

本文已收录至《Linux知识与编程》专栏&#xff01; 作者&#xff1a;ARMCSKGT 演示环境&#xff1a;CentOS 7 Linux进程初识目录 前言正文冯诺依曼体系结构操作系统简介概念操作系统的管理系统调用 进程初识进程理解进程的属性和数据进程控制块查询进程信息的相关指令进程PID 父…

机器学习笔记 Segment Anything用于图像分割的通用大模型

一、简述 人工智能中的基础模型正变得越来越重要。它们被定义为在大量数据上训练的大型人工智能模型,可以适应广泛的任务。 基础模型的早期例子是大型语言模型(LLM),如GPT和BERT。随后,该行业也看到了同样的想法被应用于多模态基础模型,如DALLE、CLIP等。基础模型这个术语…

基于深度神经网络的图像分类与训练系统(MATLAB GUI版,代码+图文详解)

摘要&#xff1a;本博客详细介绍了基于深度神经网络的图像分类与训练系统的MATLAB实现代码&#xff0c;包括GUI界面和数据集&#xff0c;可选择模型进行图片分类&#xff0c;支持一键训练神经网络。首先介绍了基于GoogleNet、ResNet进行图像分类的背景、意义&#xff0c;系统研…

S3C6410 中的 cascaded irqdomain 之 gpio

文章目录 VIC 中断 与 gpio 中断 的硬件拓扑图描述linux cascaded irq domainirq domain 初始化时获取 IRQ number(软件中断号) 时中断发生时如何调试linux irq domain 实例 VIC domain 与 gpio domain 的硬件拓扑语言描述VIC 与 INT_EINTx 的关系INT_EINTx 与 GPIO的关系INT_E…

python+excel的接口自动化测试框架实战教程(视频讲解+源码)

目录 设计流程图 Excel和结果预览 框架结构 Excel相关 日志封装 正则操作 核心操作 测试操作 测试报告发送邮件类 运行 设计流程图 这张图是我的excel接口测试框架的一些设计思路。 首先读取excel文件&#xff0c;得到测试信息&#xff0c;然后通过封装的requests方…

PyTorch中的优化器探秘:加速模型训练的关键武器

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

shell的基础学习三

文章目录 一、Shell 流程控制二、Shell 函数三、Shell 输入/输出重定向四、Shell 文件包含总结 一、Shell 流程控制 for 循环 与其他编程语言类似&#xff0c;Shell支持for循环。 for循环一般格式为&#xff1a; while 语句 while 循环用于不断执行一系列命令&#xff0c;也…

数字取证在打击和预防网络犯罪中的作用

数字取证在调查网络犯罪、防止数据泄露、在法律案件中提供证据、保护知识产权和恢复丢失的数据方面发挥着关键作用。 详细了解数字取证的重要性、如何进行网络安全调查以及数字取证专家面临的挑战。 数字取证的 4 种类型 数字取证涉及使用专门的技术和工具来检查数字设备、网…

【Python零基础学习入门篇④】——第四节:Python的列表、元组、集合和字典

⬇️⬇️⬇️⬇️⬇️⬇️ ⭐⭐⭐Hello&#xff0c;大家好呀我是陈童学哦&#xff0c;一个普通大一在校生&#xff0c;请大家多多关照呀嘿嘿&#x1f601;&#x1f60a;&#x1f618; &#x1f31f;&#x1f31f;&#x1f31f;技术这条路固然很艰辛&#xff0c;但既已选择&…

SPSS如何进行均值比较和T检验之案例实训?

文章目录 0.引言1.均值过程2.单样本T检验3.独立样本T检验4.成对样本T检验 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对SPSS进行了学习&#xff0c;本文通过《SPSS统计分析从入门到精通》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;本文对均值比较…

Day5_创建mapper文件/编写查询语句sql

上一节主要介绍了springboot集成mybatis进行&#xff0c;以及后端开发思想。这一节主要编写sql映射文件&#xff0c;即真正的sql语句。实现增删改查用户数据&#xff0c;以及配置application.yml或者configuration文件实现控制台打印SQL语句。 接着上一节编写续写~~~~~~ 目录…