Leetcode刷题day1|数组一|704.二分查找,27.移除元素,35.搜索插入位置

news2025/7/7 20:51:38

一、面试中数组相关理论知识

数组是非常基础的数据结构,在面试中,考察数组的题目一般在思维上都不难,主要是考察对代码的掌控能力。也就是说,想法很简单,但实现起来 可能就不是那么回事了。

要想真正理解数组在内存中的存储方式,就必须知道数组在内存中的存储方式。

重点就是数组在内存中的存储。

  1. 数组是存储在连续内存空间上的相同类型数据的集合。

  2. 数组的下标都是从0开始的

  3. 数组的内存空间的地址是连续的

  4. C++中二维数组在内存中也是连续的,java中没有指针,不对程序猿暴露元素的地址,寻址操作完全交给虚拟机,(即使打印也是经过哈希得到的虚拟地址)所以二维数组的每个元素【一维数组】内部可能是连续的,但是二维数组的元素之间可能不是连续的。

  5. 数组元素在内存空间中的地址是连续的,这就意味着我们在进行删除和添加元素的时候需要移动其他元素的地址。

  6. 数组的元素是不能删除的,只能进行覆盖

  7. 建议:能不能用库函数取决于用库函数是解决这个题目中的一小步,知不知道源码和源码实现以及时间复杂度,如果都是yes,那么可以使用,否则就是建议不用

二、二分查找问题

题目链接

思路

最基本的二分查找

注意事项

  1. 在while循环中,如果不是target值,除了修改left或者right值之外,还要修改mid的值。
  2. 对于mid的求法,需要用到一个数学技巧。不要直接right和left直接相加,而是用左端值+两者差值的一半。这样做的目的是为了防止right和left的和超出int所能表示的最大范围,导致溢出。

AC代码

class Solution {
    public int search(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        int mid=left+(right-left)/2;
        while(left<=right){
            if(nums[mid]==target){
                return mid;
            }else if(nums[mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
            mid=left+(right-left)/2;
        }
        return -1;
    }
}

三、移除元素

题目链接

思路

优化后的核心思路:双指针

因为此题要求空间复杂度为O(1),也就是说我们不能通过开辟临时数组来解题。那么很显然,这道题需要我们遍历数组,并进行原地修改数组,并且返回“新数组的长度”。

那么,我们应该怎样删除数组元素呢?

时间复杂度为O(n^2)

首先,移除也就是从把元素从数组中删除。但是我们知道数组其实不能从根本上删除元素,而是通过覆盖元素、同时**控制访问地址权限(即“修改数组长度”)**的方式来实现“删除元素的效果的”。

因此,我们可以通过设置cnt变量,初始值为0,来记录当前数组中需要删除的个数,并且在数组遍历的时候减去cnt个数。之后一满足条件就往前覆盖。

我们很容易写出这样的代码,但是它真的能ac吗?have a try.

public int removeElement(int[] nums, int val) {
    int cnt=0;
    for (int i = 0; i < nums.length-cnt; i++) {
        if(nums[i]==val){
            for (int j = i; j <nums.length-1; j++) {
                nums[j]=nums[j+1];
            }
            cnt++;
        }
    }
    return nums.length-cnt;
}

在这里插入图片描述

这是什么原因呢?我们调试看看是为什么

调试到这里我们可以发现,第一个2被删除了,但是紧挨的2并没有删除,此时就已经开始遍历下一个位置了。
在这里插入图片描述

很容易分析出来,是因为我们把后边的值往前拿了,但是后边的值到底是不是target值呢?我们不得而知。

倘若此时我们对代码不加修改,那么它就直接跳到下一个位置去了。相当于图示这种情况。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2WNqOsxp-1668578022005)(F:\typora插图\image-20221116114544401.png)]

因此,为了防止这种情况,我们在每次覆盖完成之后需要再次访问这个位置的元素,通过i–实现,看是不是target值。

这样写出的代码时间复杂度是O(n^2)、空间复杂度是O(1)

那么有没有办法将时间复杂度优化成O(n)呢?答案是肯定的

用双指针代替了一层for循环需要做的事情

慢指针是“新数组中的下标”,快指针是老数组中的不需要删除的元素对应的下标

int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
    if (val != nums[fastIndex]) {
        nums[slowIndex++] = nums[fastIndex];
    }
}
return slowIndex;

注意事项

  1. 遍历的范围是0~nums.length-cnt
  2. 进行覆盖之后需要注意i–

AC代码

class Solution {
    public int removeElement(int[] nums, int val) {
        int cnt=0;
        for (int i = 0; i < nums.length-cnt; i++) {
            if(nums[i]==val){
                for (int j = i; j <nums.length-1; j++) {
                    nums[j]=nums[j+1];
                }
                i--;
                cnt++;
            }
        }
        return nums.length-cnt;
    }
}

四、寻找插入位置

题目链接

思路

核心思路:二分查找/双指针

  1. 如果在原数组中存在,直接返回对应的位置,此时就等价于上边的二分查找
  2. 如果在元素中不存在,直接跳出循环,此时的left对应的下标恰好是对应的位置。

AC代码

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        int mid=left+(right-left)/2;
        while(left<=right){
            if(nums[mid]==target){
                return mid;
            }else if(nums[mid]>target){
                right=mid-1;
            }else{
                left=mid+1;
            }
            mid=left+(right-left)/2;
        }
        return left;
    }
}

五、总结

  1. 数组在内存中是连续存储的,不能够实现物理意义上的删除,只能实现逻辑上的删除元素。
  2. 逻辑删除元素的手段就是通过覆盖。
  3. 二分查找题目中需要注意每次访问后都需要改变mid的值
  4. 移除元素题目中需要注意每次覆盖后都需要i–,用于解决相邻待删除元素的问题,同时需要注意遍历的范围是在变化的。

二分法|二分查找法|二分搜索法|

二分易错点

1.while循环中的条件是left<right还是left<=right呢

2.当nums[mid]>target时,我们是更新左区间的右边界的,执行的操作是right=mid还是mid-1呢

相关概念

区间的类型

  1. 左闭右闭
  2. 左闭右开
  3. 左开右闭

区间的类型决定了上边两个易错操作究竟怎么处理 。在处理的边界时,我们需要坚持不变量。一开始是半开半闭,处理出来的结果也必须是半开半闭,反之,必须是全闭区间。

代码实现

左闭右闭

1.left可以等于right

  1. mid对应的大于target,那么应该是right=mid-1;
int left=0;
int right=nums.length-1;
int mid=left+(right-left)/2;
while(left<=right){
    if(nums[mid]==target){
        return mid;
    }else if(nums[mid]<target){
        left=mid+1;
    }else{
        right=mid-1;
    }
    mid=left+(right-left)/2;
}
return -1;

左闭右开

  1. left不可以等于right【否则区间不合法】

  2. mid对应的大于target,区间中本来就不包含mid,那么是right=mid就可以了;

int left=0;
int right=nums.length-1;
int mid=left+(right-left)/2;
while(left<right){
    if(nums[mid]==target){
        return mid;
    }else if(nums[mid]<target){
        left=mid;
    }else{
        right=mid;
    }
    mid=left+(right-left)/2;
}
return -1;

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

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

相关文章

【树状数组】前缀和问题

一、引子 给你一个数组 nums &#xff0c;请你完成两类查询。 其中一类查询要求更新数组 nums 下标对应的值另一类查询要求返回数组 nums 中索引 left 和索引 right 之间&#xff08; 包含 &#xff09;的nums元素的和 题目只是一个用来检测我们思想的东西&#xff0c;比如这…

Android BottomSheet总结

文章目录Android BottomSheet总结BottomSheetBottomSheetDialogBottomSheetDialogFragment全屏无阴影BottomSheetDialogFragment代码下载Android BottomSheet总结 BottomSheet XML布局&#xff1a; <?xml version"1.0" encoding"utf-8"?> <an…

C++ 条件变量的使用

绪论 并发编程纷繁复杂&#xff0c;其中用于线程同步的主要工具——条件变量&#xff0c;虽然精悍&#xff0c;但是要想正确灵活的运用却并不容易。 对于条件变量的理解有三个难点&#xff1a; 为什么wait函数需要将解锁和阻塞、唤醒和上锁这两对操作编程原子的&#xff1f;为…

MCMC学习笔记-马尔科夫链概述

参考文章&#xff1a;MCMC(二)马尔科夫链 - 刘建平Pinard - 博客园 写给小白看的马尔科夫链&#xff08;Markov Chain&#xff09;最佳入门教程_许进进的博客-CSDN博客_markov链 目录 1.马尔科夫链概述 1.1股票市场模型 2.马尔科夫链模型状态转移矩阵的性质 (本节重点) 2.…

小程序容器技术加持下,企业自主打造小程序生态

小程序是一种不用下载就能使用的应用&#xff0c;也是一项门槛非常高的创新&#xff0c;经过将近两年的发展&#xff0c;已经构造了新的小程序开发环境和开发者生态。 据对公开资料进行统计&#xff0c;2021年全网小程序数量已超700万&#xff0c;其中微信小程序开发者突破300…

java使用world模板动态生成PDF文件

根据项目需求&#xff0c;需要用到一个功能&#xff0c;根据页面参数需要动态的生成一个world&#xff0c;并将world生成两份PDF文件&#xff0c;一份正式文件&#xff0c;一份临时的电子文件&#xff08;带有二维码&#xff0c;扫描可以下载正式文件的电子版本&#xff09;。同…

JAVA开发(nginx)

主要描述下面4个内容&#xff1a; 1.Nginx的正向代理和反向代理 2.Nginx的动静分离 3.Nginx的负载均衡 4.Nginx的配置详解 解释&#xff1a; Nginx的正向代理&#xff1a;代理的是客户端。 Nginx的反向代理&#xff1a;代理的是服务端。在web服务中&#xff0c;一般都是…

2022年“网络安全”赛项驻马店市赛选拔赛 任务书

2022年“网络安全”赛项驻马店市赛选拔赛 一、竞赛时间 共计3小时。 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段单兵模式系统渗透测试 任务一 Windows操作系统渗透测试 100分钟 100 任务二 Linux操作系统渗透测试 150 任务三 数字取证调查 150 任务四 …

vscode不能打开终端问题

遇到vscode不能打开终端问题&#xff0c;一直以为是安全软件限制问题&#xff0c;也没搜到解决方案&#xff0c;因为影响也不大&#xff0c;就没有管。 最近&#xff0c;要用vscode调试代码&#xff0c;发现不能打开终端&#xff0c;没法玩了&#xff0c;又来看这个问题&#…

【图像隐藏】基于matlab像素预测和位平面压缩的加密图像可逆数据隐藏【含Matlab源码 2218期】

⛄一、加密图像可逆数据隐藏简介 1 信息隐藏技术概述 信息隐藏技术是把秘密信息隐藏在多媒体信息中的一种方法。图像是最适合信息隐藏的数据载体。信息隐藏的方法主要有数字水印技术、隐写术等。 信息隐藏可以分为有损信息隐藏与可逆信息隐藏信息隐藏技术, 区别在于接收端是否…

【虚幻引擎UE】UE5 简单实现范围计算圆圈绘制

先来看看可以实现的效果&#xff1a; 一、实现快速绘制圆圈的C函数 .cpp文件 #include "drawPolygon.h" #include "Components/LineBatchComponent.h" #include "Engine/World.h" #include "EngineGlobals.h" #include "Prim…

墨西哥专线详解:墨西哥专线时效多久,墨西哥专线价格多少?

墨西哥专线是国内直飞墨西哥或者海运墨西哥的专线物流服务&#xff0c;从中国到墨西哥的物流大约需要3到30天。不同的运输方式到墨西哥的时间不同。国际快递是最快的。通常3到5天就可以完成目的地派送&#xff0c;最慢的是海运专线&#xff0c;到墨西哥大约需要20到30天才能到达…

隐式神经表示二:超分网络学习傅里叶系数Local Texture Estimator for Implicit Representation Function

文章目录1. Local Texture Estimator for Implicit Representation Function1. 通过隐式神经网络表示方法 实现 超分辨率。2. 在编码器和解码器之间作者引入一个 local texture estimator3. 代码分析整体框架生成图像特征&#xff0c;编码器是一个常规的卷积网络&#xff0c;文…

【Pytorch with fastai】第 8 章 :协同过滤深入探讨

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

十四、Java String 类

Java String 类 字符串广泛应用 在 Java 编程中&#xff0c;在 Java 中字符串属于对象&#xff0c;Java 提供了 String 类来创建和操作字符串。 创建字符串 创建字符串最简单的方式如下: String str "xxx"; 在代码中遇到字符串常量时&#xff0c;这里的值是 &q…

大数据开源平台好在哪里?

当前是大数据发展时代&#xff0c;对于企业而言需要紧紧抓住契机乘势而上&#xff0c;利用好内部数据做好数字化转型&#xff0c;可以为企业带来更高的发展空间。大数据开源平台是助力企业提升办公效率的软件平台&#xff0c;那么&#xff0c;哪里有这样的大数据开源平台&#…

关于Git使用:fatal: Could not read from remote repository.的报错问题解决

目录 一&#xff1a;问题描述 二&#xff1a;解决过程 1&#xff0c;增加账号及邮箱 2&#xff0c;添加秘钥&#xff1a; 3&#xff0c;获取公钥并将其设置到云效里面 4&#xff0c;宝塔终端 解除密码 三&#xff1a;解决截图 一&#xff1a;问题描述 我们公司的版本仓…

【布隆过滤器】世界上大概有1 亿种小蛋糕,客户康宝要求这辈子不吃重复的小蛋糕。

文章目录需求概念思想问题优点缺点应用手写布隆过滤器补充需求 现在客户康宝有一个需求&#xff1a;世界上大概有 1 亿 种小蛋糕&#xff0c;康宝要求这辈子不吃重复种类的小蛋糕。 因为小蛋糕的种类很大可能只会增加&#xff0c;而不会减少&#xff0c;面对这种大数据量的要…

静态分析 Qt Ceator 组织的工程代码

文章目录Missing reference in range-for with non trivial type (QString) [clazy-range-loop]Slots named on_foo_bar are error prone [clazy-connect-by-name]Call to virtual method FlowLayout::takeAt during destruction bypasses virtual dispatch [clang-analyzer-op…