数组深入学习感悟

注:本文学习借鉴于《代码随想录》

一.介绍数组

数组是储存在连续内存空间中的相同类型数据的集合

数组名的理解:

数组名就是数组⾸元素(第⼀个元素)的地址是对的,但是有两个例外:
sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,
单位是字节
&数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素
的地址是有区别的)
除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址
数组中的元素不能删除,只能覆盖。

二.数组解题法

下面我们介绍数组解决问题的几大方法。

1.二分查找

适用类型:对于数组中在范围查找元素的位置,求解平方根,以及插入元素等。

使用前提:二分查找使用前一定要观察元素是否已排好位置

二分查找主要有以下两种写法:

1.1.左闭右闭[left,right]

该写法注意点:(本文不再进行基础实现讲解,可以翻看我的之前文章,有实现过程)
1.while (left <= right) 要使⽤ <= ,因为 left == right 是有意义的,所以使⽤ <=
2.if (nums[middle] > target) right 要赋值为 middle - 1 ,因为当前这个 nums[middle] ⼀定不是 target ,那么接下来要查找的左区间结束下标位置就是 middle - 1

对于leedcode这题:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

就是典型的第一类写法

下面是我对于该题的C语言解法代码:

int search(int* nums, int numsSize, int target) 
{int left=0;int right=numsSize-1;while(left<=right){int mid=(left+right)/2;if(nums[mid]<target){left=mid+1;}else if(nums[mid]>target){right=mid-1;}else{return mid;}}return -1;
}
时间复杂度: O(log n)
空间复杂度: O(1)

1.2.左闭右开[left,right)

注意点:

1.while (left < right) ,这⾥使⽤ < , 因为 left == right 在区间 [left, right) 是没有意义的
2.if (nums[middle] > target) right 更新为 middle ,因为当前 nums[middle] 不等于 target ,去左区间继续寻找,⽽寻找区间是左闭右开区间,所以right 更新为 middle ,即:下⼀个查询区间不会去⽐较 nums[middle]。
还是刚才那题,现在我们用第二种方法实现它:
int search(int* nums, int numsSize, int target) 
{int left=0;int right=numsSize;//注意right现在是被赋值为numsSizewhile(left<right){int mid=(left+right)/2;if(nums[mid]<target){left=mid+1;}else if(nums[mid]>target){right=mid;//由于用边界为空,所以right=mid,而不是right=mid-1}else{return mid;}}return -1;
}

补充:如果你想问有没有左开右闭的二分查找,我想说的是有,当使用的意义不大,所以作者这里就不讲了。

下面是推荐的练习题:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台   (69.x 的平⽅根)

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台        (367.有效的完全平⽅数)

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台           (35.搜索插⼊位置)
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台        (34.在排序数组中查找元素的第⼀个和最后⼀个位置)

这些题可能对你有点难,请加油,我相信你一定可以的。

2.双指针法(重点)

解释:双指针法是定义两个有关联的变量,可能是指针,也可能是整数,通过他们实现对数组的操作,使得高效,快捷。

具体的我们来在题目中去感受吧!

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

对于leedcod这题,大家第一反应可能就是暴力出手,疯狂遍历数组,一个for循环不行,那我两个,再不行,再加,但是现在来看看大佬们的思路,让你直呼666……
双指针法就是这题的良方妙药,下面我带着大家用双指针来实现它
由于是数组,我们定义两个整型变量,即slow和fast,表示快慢指针
快指针:寻找新数组的元素 ,新数组就是不含有⽬标元素的数组
慢指针:指向更新新数组下标的位置
看代码:
int removeElement(int* nums, int numsSize, int val) 
{//双指针法int src=0;int dest=0;while(src<numsSize){if(nums[src]!=val){nums[dest++]=nums[src++];}else{src++;}}return dest;
}

是不是大呼学到了。

关于双指针的使用场景,大家需要多做题,自己把握,这样慢慢可能就能感受的啥题目是考察双指针了。

来再带着大家看一题:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

对于这题,我们就直接开始双指针吧!

这题比较特殊,它是有序的,又是问平方,只需要比较负数的平方与整数平方关系即可,大家想想,如果我们定义两个指针,一个指向头,一个指向尾,是不是就可以最快的进行排好序。

看代码实现

/*** Note: The returned array must be malloced, assume caller calls free().*/
int* sortedSquares(int* nums, int numsSize, int* returnSize) 
{*returnSize = numsSize;int* arr=(int*)malloc(numsSize*sizeof(int));int n=0;int m=numsSize-1;int c=numsSize-1;while(n<=m){int i=nums[n]*nums[n];int j=nums[m]*nums[m];if(i>j){arr[c--]=i;n++;}else//j>=i{arr[c--]=j;m--;}}return arr;
}
双指针⻛骚起来,也是⽆敌(转自程序员Carl)
下面给大家推荐几道好题:(不用说谢了,这种好东西,一定要拿出来共享,当时快把我写吐了)
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

刷完绝对对于双指针有一定的使用感觉了。

3.滑动窗口

如果大家深入了解过数组,就一定听过数组恶魔---滑动窗口
对于滑动窗口,连leedcode上都是中等题起步
下面我们就一题进行了解:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
滑动窗⼝, 就是不断的调节⼦序列的起始位置和终⽌位置,从⽽得出我们要想的结果
我们应该可以看出,如果我们纯暴力来解决这题,就是两个for循环,但是如果用滑动窗口,一个for循环即可,下面来看看实现过程:
⾸先要思考 如果⽤⼀个 for 循环,那么应该表示滑动窗⼝的起始位置,还是终⽌位置。 如果只⽤⼀个for 循环来表示 滑动窗⼝的起始位置,那么如何遍历剩下的终⽌位置? 此时难免再次陷⼊ 暴⼒解法的怪圈。 所以只⽤⼀个for 循环,那么这个循环的索引,⼀定是表示滑动窗⼝的终⽌位置。
在本题中实现滑动窗⼝,主要确定如下三点:
窗⼝内是什么?
如何移动窗⼝的起始位置?
如何移动窗⼝的结束位置?
窗⼝就是 满⾜其和 s 的⻓度最⼩的 连续 ⼦数组。
窗⼝的起始位置如何移动:如果当前窗⼝的值⼤于 s 了,窗⼝就要向前移动了(也就是该缩⼩了)。
窗⼝的结束位置如何移动:窗⼝的结束位置就是遍历数组的指针,也就是 for 循环⾥的索引.
看代码实现过程:
int minSubArrayLen(int target, int* nums, int numsSize) 
{int size=0;int result=INT_MAX;int left=0;int sum=0;for(int right=0;right<numsSize;right++){sum+=nums[right];while(sum>=target){size=right-left+1;result=result<=size?result:size;sum-=nums[left++];}}return result==INT_MAX?0:result;
}

时间复杂度直接从O(N*N)降到了O(N),可见这种方法的强大。

推荐大家去B站看代码随想录视频,可能理解更加深入。

下面给大家推荐题目吧:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
这两题是真的难啊!!!加油
最后,给小编点赞呗kiss!

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

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

相关文章

Mybatis-Plus讲义v1.0

Mybatis-Plus 课程目标 了解Mybatis-Plus 整合Mybatis-Plus 通用CRUD Mybatis-Plus的配置 条件构造器 Mybatis-Plus 的Service封装 代码生成器 1 Mybatis-Plus介绍 1.1 Mybatis-Plus介绍 MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&…

Ubuntu-20.04.2 mate 上安装、配置、测试 qtcreator

一、从repo中安装 Ubuntu-20.04.2的repo中&#xff0c;qtcreator安装包挺全乎的&#xff0c;敲完 sudo apt install qtcreator 看一下同时安装和新软件包将被安装列表&#xff0c;压缩包252MB&#xff0c;解压安装后933MB&#xff0c;集大成的一包。 sudo apt install qtcrea…

现代雷达车载应用——第3章 MIMO雷达技术 3.2节 汽车MIMO雷达波形正交策略

经典著作&#xff0c;值得一读&#xff0c;英文原版下载链接【免费】ModernRadarforAutomotiveApplications资源-CSDN文库。 3.2 汽车MIMO雷达波形正交策略 基于MIMO雷达技术的汽车雷达虚拟阵列合成依赖于不同天线发射信号的可分离性。当不同天线的发射信号正交时&#x…

软件设计模式:UML类图

文章目录 前言一、&#x1f4d6;设计模式概述1.软件设计模式的产生背景2.软件设计模式3.设计模式分类 二、&#x1f4e3;UML图1.类图概述2.类的表示法3.类与类之间的关系关联关系&#xff08;1&#xff09;单向关联&#xff08;2&#xff09;双向关联&#xff08;3&#xff09;…

CCF编程能力等级认证GESP—C++6级—20230923

CCF编程能力等级认证GESP—C6级—20230923 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)小杨买饮料小杨的握手问题 答案及解析单选题判断题编程题1编程题…

vba中字典的应用实例

vba中熟练使用字典可以帮我们解决很多问题&#xff0c;以下为字典的应用方法及案例&#xff1a; Sub dictionary() Dim d As New dictionary 定义字典 Dim mykey As Variant Dim myitems d.Add "1100000", "身份证" 字典录入key关键字和item条目 d.Add &q…

C语言归并排序(合并排序)算法以及代码

合并排序是采用分治法&#xff0c;先将无序序列划分为有序子序列&#xff0c;再将有序子序列合并成一个有序序列的有效的排序算法。 原理&#xff1a;先将无序序列利用二分法划分为子序列&#xff0c;直至每个子序列只有一个元素(单元素序列必有序)&#xff0c;然后再对有序子序…

AtCoder Beginner Contest 333 A~F

A.Three Threes&#xff08;循环&#xff09; 题意&#xff1a; 给出一个正整数 N N N&#xff0c;要求输出 N N N个 N N N 分析&#xff1a; 按要求输出即可 代码&#xff1a; #include <bits/stdc.h> using namespace std;void solve() {int n;cin >> n;fo…

「遮天」段德互坑叶凡,期满至宝绿铜下落,老疯子限定回归

Hello,小伙伴们&#xff0c;我是拾荒君。 《遮天》第36集已经更新了&#xff0c;我迫不及待地跟随漫迷的脚步&#xff0c;前往观看。这一集中&#xff0c;叶凡在途中偶遇了一个醉酒的段德。这个段德之前曾沦陷在阴坟之中&#xff0c;如今能够逃出&#xff0c;可见他的实力深不…

ADC模拟/数字转换器

ADC是什么&#xff1f; 全称&#xff1a; Analog-to-Digital Converter &#xff0c;指模拟 / 数字转换器 它是一种电子设备或电路&#xff0c;用于将连续的模拟信号转换为相应的数字形式&#xff0c;以便于数字系统进行处理。模拟信号是连续变化的&#xff0c;而数字系统则处…

sensitive-word 敏感词之 DFA 双数组实现源码学习

拓展阅读 敏感词工具实现思路 DFA 算法讲解 敏感词库优化流程 java 如何实现开箱即用的敏感词控台服务&#xff1f; 各大平台连敏感词库都没有的吗&#xff1f; v0.10.0-脏词分类标签初步支持 v0.11.0-敏感词新特性&#xff1a;忽略无意义的字符&#xff0c;词标签字典 …

分享一个项目——Sambert UI 声音克隆

文章目录 前言一、运行ipynb二、数据标注三、训练四、生成总结 前言 原教程视频 项目链接 运行一个ipynb&#xff0c;就可操作 总共四步 1&#xff09;运行ipynb 2&#xff09;数据标注 3&#xff09;训练 4&#xff09;生成 一、运行ipynb 等运行完毕后&#xff0c;获得该…

全国1900+监测站点空气质量日数据,shp/excel格式,2023年最新数据

基本信息. 数据名称: 全国1900监测站点空气质量监测日数据 数据格式: shpexcel 时间版本&#xff1a;2023年 数据几何类型: 点 数据精度&#xff1a;全国 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1province省…

echarts饼图点击区块事件

loadEchart: function (echartname, data) {option {title: {text: ,subtext: ,left: center},tooltip: {trigger: item,formatter: {c}%},legend: {orient: vertical,left: left,},series: [{name: ,type: pie,radius: 70%,data: [[name>合同额,value>12312312],],labe…

ros2机器人在gazebo中移动方案

原文连接Gazebo - Docs: Moving the robot (gazebosim.org) 很重要的地方&#xff1a;使用虚拟机运行Ubuntu的时候&#xff0c;需要关闭”加速3D图形“的那个选项&#xff0c;否则gazebo无法正常显示。 Moving the robot&#xff08;使用命令移动机器人示例&#xff09; In t…

SpringBoot知识点回顾01

Spring是为了解决企业级应用开发的复杂性而创建的&#xff0c;简化开发。 Spring是如何简化Java开发的 为了降低Java开发的复杂性&#xff0c;Spring采用了以下4种关键策略&#xff1a; 1、基于POJO的轻量级和最小侵入性编程&#xff0c;所有东西都是bean&#xff1b; 2、通…

《JVM由浅入深学习【一】 2023-12-19》JVM由简入深学习提升

JVM由浅入深一&#xff08;类加载&#xff09; JVM的类加载1. java运行时是什么时候被加载的&#xff1f;2. JVM类加载过程大致阶段3. 父类与子类初始化各个类型顺序4. 什么是类加载器&#xff1f;6. 双亲委派机制 JVM的类加载 1. java运行时是什么时候被加载的&#xff1f; …

TikTok获客工具开发,这些代码不能少!

随着TikTok的全球影响力不断扩大&#xff0c;越来越多的企业和个人开始将目光投向这个短视频平台。 为了在竞争激烈的市场中脱颖而出&#xff0c;开发一款高效的TikTok获客工具成为了迫切的需求&#xff0c;而在开发过程中&#xff0c;掌握一些基础源代码是必不可少的。 本文…

虾皮ERP系统:提升电商企业管理效率和水平的利器

虾皮ERP&#xff08;Enterprise Resource Planning&#xff0c;企业资源规划&#xff09;系统是电商企业管理业务流程和资源的重要工具。通过整合企业的各种功能模块&#xff0c;如采购、销售、库存和财务等&#xff0c;虾皮ERP系统实现了数据共享和流程自动化&#xff0c;从而…

Java自动化测试系列[v1.0.0][多种数据驱动实现附源码]

数据驱动测试是自动化测试中一种重要的设计模式&#xff0c;这种设计模式可以将测试数据和测试代码分开&#xff0c;实现数据与代码解耦&#xff0c;与此同时还能够实现一次任务中使用不同的数据来执行执行相同的测试脚本&#xff0c;因此它会使得我们的代码层次结构清晰&#…