1.让数组动起来

news2025/2/24 18:31:53

概述

对数组进行分析,目标如下

  • 线性表的概念
  • 数组的存储结构
  • 数组查询,插入,删除操作的特点及对应的时间复杂度
  • 刷题(盛最多水的容器)

线性表

在数据结构中,数据的逻辑结构分为线性结构非线性结构
线性结构: n个数据元素有序集合,特征如下:

  1. 集合中必存在唯一的一个第一个元素
  2. 集合中必存在唯一的一个最后的元素
  3. 除最后元素之外,其它数据元素均有唯一的 后继
  4. 除第一元素之外,其它数据元素均有唯一的前驱

数据结构中线性结构指的是数据元素之间存在着一对一的线性关系的数据结构,这个线性并不是说一定是直线,常见的线性数据结构有:数组(一维),链表队列;表现形式如下:
在这里插入图片描述
相对应于线性结构,非线性结构的逻辑特征是一个结点元素可能对应多个直接前驱和多个后驱,比如: 等,如下图
在这里插入图片描述

数组基础

概念和结构

数组(Array)是一种用连续的内存空间存储相同数据类型数据的线性数据结构

int[] array = new int[]{10,20,30}

内存结构中如下图
在这里插入图片描述
数组的表示方式:使用下标来获取数组元素数据
在这里插入图片描述
操作平台是如何根据下标来找到对应元素的内存地址?

拿一个长度为10的数组来举例 ,int[] a = new int[10],在下面图中,计算机给数组分配了一块连续的空间,100-139,其中内存的起始地址为 baseAddress=100

在这里插入图片描述
计算机给每个内存单元都分配了一个地址,通过地址来访问其数据,因此访问数组中某个元素时,首先要经过一个寻址公式计算要访问的元素,在内存中的地址:

a[i] = baseAddress + i * dataTypeSize

其中dataTypeSize代表数组中元素类型的大小,在这个例子中,存储的是int型的数据,因此dataTypeSize=4 个字节

下标为什么从0开始而不是1呢?

个人想来,从数组存储的内存模型上来看,下标最确切的定义应是偏移(offset),如果用array来表示数组的首地址,array[0]就是偏移为0的位置,也就是首地址,array[k] 就表示偏移ktypeSize 的位置,所以计算array[k]的内存地址用这个公式

array[k]_address = baseAddress + k * typeSize

如果下标从1开始,那么计算array[k]的内存地址会变成

array[k]_adress = baseAddress + (k-1) * typeSize

对比两个公式,不难发现从数组下标1开始去访问数组元素,对于 cpu 来说,多了一次减法指令

另一个原因,c语言设计者使用0开始作为数组的下标,后来的高级语言沿用了这一设计(也有从1开始的)

数组的特点

查询O(1)

数组元素的访问是通过下标来访问的(不是遍历),计算机通过数组的首地址和寻址公式能够很快速的找到想要访问的元素

public class Demo {
	public static void main(String[] args) {
		int[] array = new int[]{10, 20, 30};

		System.out.println("打印:" + test(array, 1));
	}

	public static int test(int[] a, int i) {
		return a[i];
	}
}

代码的执行次数并不会随着数组的数据规模大小变化而变化,是常数级的,所以查询单个数据操作的时间复杂度为O(1)

插入删除O(n)

数组是一段连续的内存空间,因此为了保证数组的连续性会使用数组的插入和删除的效率变的很低

数据插入

假设数组的长度为n,现在需要将一个数据插入到数组中第k个位置,为了将第k个位置腾出来给新的数据,需要将第k~n这部分的元素都顺序的往后挪一位,如下图所示:
在这里插入图片描述
插入操作对应的时间复杂度是多少呢?

最好的情况下是O(1),最坏的情况下是O(n),平均情况下的时间复杂度是O(n)

数据删除

同数据插入可得:如果要删除第k个位置的数据,为了内存的连续性,也需要搬移数据,不然中间就会出现空洞,内存就不连续了,时间复杂度仍然为O(n)

如果要提高数据删除的效率呢?

在某些特殊场景下,并不一定非得追求数组中数据的连续性;如果将多次删除操作集中在一起执行,删除的效率是不是会提高很多
example:数组a[6]中存了6个元素:a1,a2,a3,a4,a5,a6,现在要依次删除a1,a2这两个元素
在这里插入图片描述
为了避免a3,a4,a5,a6这几个数据被搬移两次,可以先记录下已经删除的数据,每次的删除操作并不是真正的移数据,只是记录数据 已经被删除,当数组没有更多的空间存储时,再触发执行一次真正的删除操作,这样就大大减少了删除操作导致的数据搬移
这种思想,就是jvm标记清除垃圾回收算法的核心思想

刷题

盛最多水的容器

盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。

i 条线的两个端点是 (i, 0)(i, height[i]) 两个端点的距离(高度)即数组下标i的值
在这里插入图片描述

暴力美学,朴素解法

public class Demo {
	public static void main(String[] args) {
		System.out.println(maxArea(new int[]{1, 8, 6, 2, 5, 4, 8, 3, 7}));
	}

	public static int maxArea(int[] height) {
		int max = 0;
		for (int i = 0; i < height.length; i++) {
			for (int j = i + 1; j < height.length; j++) {
				// 比较两条线,哪个低(得出宽高算面积)
				int lineHeight = Math.min(height[i], height[j]);
				int width = j - i;
				max = Math.max(max, width * lineHeight);
			}
		}
		return max;
	}
}

双指针,速度快

示例1图中所示,要面积最大,要么x轴要宽,要么 y 轴要高,所以,开始x轴最大,算面积,后面比较两上y 轴,y轴相对较小的继续向前或向后移动,这就是双指针

public class Demo {
	public static void main(String[] args) {
		System.out.println(maxArea2(new int[]{1, 8, 6, 2, 5, 4, 8, 3, 7}));
	}
	public static int maxArea2(int[] height) {
		int max = 0;
		// 第一步 , x轴距离最大,算其面积
		int i = 0;
		int j = height.length - 1;
		while (i != j) {
			// i = j 已无计算的必要
			int area = Math.min(height[i], height[j]) * (j - i);
			if (height[i] < height[j]) {
				// 如果前指针小于后面的指针,即 height[i] 的值小于 height[j] ,则移动 i ,寻找更大的 y 轴
				i++;
			} else {
				// 反过来一样
				j--;
			}
			max = Math.max(area, max);
		}
		return max;
	}
}

结束

数组至此就结事了,如有问题欢迎评论!

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

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

相关文章

在 Visual Studio 中远程调试 C++ 项目

目录 一、说明二、下载远程工具1. 官网下载2. 自己电脑上拷贝 三、 运行远程工具四、本机Visual Studio配置五、自动部署 一、说明 参考官方文档&#xff1a;https://learn.microsoft.com/zh-cn/visualstudio/debugger/remote-debugging-cpp?viewvs-2022 二、下载远程工具 …

【C语言】calloc()函数详解(动态内存开辟函数)

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 一.calloc()函数简介 我们先来看一下cplusplus.com - The C Resources Network网站上calloc()函数的基本信息&#xff1a; 1.函数功能 可以看到,calloc()函数的功能是:为num个大…

FastAPI框架学习笔记(快速入门FastAPI框架)

1. 写在前面 今天整理一篇后端框架的笔记&#xff0c; fastapi框架是比较主流的后端异步web框架&#xff0c;关键是python语言可以写&#xff0c;正好公司最近安排了一些后端服务的活&#xff0c; 所以就看了一个fastapi框架的入门课程(链接在底部)&#xff0c;完成任务&#…

用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程

&#x1f9f8;注&#xff1a;不要看我的文件多&#xff0c;那是我的其他项目&#xff0c;这个项目所用的文件我会全部用红框框起来&#xff0c;没框的部分不用管&#xff0c;前端两个文件&#xff0c;后端一个文件 &#x1f4dc; 目录 首先&#xff0c;定义前后端交互接口 然…

电子器件 电感

拿一根导线在笔上绕几圈&#xff0c;取下来就是一个空心电感&#xff0c;如果拿一个铁芯&#xff0c;在铁芯上绕相同的圈数&#xff0c;加了的铁芯的电感量是没有加铁芯的几千倍甚至上万倍&#xff0c;所以电感一般是有铁芯的。 下图是电感的模型&#xff0c;L 是理想电感&…

招生报名缴费小程序开发笔记(上)

前期调研 1.数字化趋势&#xff1a; 随着社会的数字化转型&#xff0c;越来越多的教育机构倾向于采用数字工具来简化和优化他们的招生和报名过程。招生报名缴费小程序是应对这一趋势的一种解决方案&#xff0c;可以提供高效、方便、快速的在线招生渠道。2.用户需求&#xff1a…

强化学习中值函数应用示例

一、Gridworld Gridworld是一个用于教授强化学习概念的简化的电子游戏环境。它具有一个简单的二维网格&#xff0c;智能体可以在其中执行动作并获得奖励。这个环境是有限的&#xff0c;因为它有一个明确的开始和结束状态&#xff0c;以及一组确定的动作和奖励。 在Gridworld中&…

C++二分查找算法的应用:最长递增子序列

涉及知识点 二分查找 单调映射 源码下载 点击下载源码 题目 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xf…

Rust 语言介绍及安装

目录 1、简介 1.1 为什么选择Rust 高性能 可靠性 生产力 1.2 用 Rust 构建应用 命令行 WebAssembly 网络 嵌入式 2、安装 Rust Windows 的 Linux 子系统&#xff08;WSL&#xff09; 检查Rust 是最新的 卸载Rust版本&#xff1a; Cargo&#xff1a;Rust 的构建工…

读图数据库实战笔记03_遍历

1. Gremlin Server只将数据存储在内存中 1.1. 如果停止Gremlin Server&#xff0c;将丢失数据库里的所有数据 2. 概念 2.1. 遍历&#xff08;动词&#xff09; 2.1.1. 当在图数据库中导航时&#xff0c;从顶点到边或从边到顶点的移动过程 2.1.2. 类似于在关系数据库中的查…

我在Vscode学OpenCV 初步接触

OpenCV是一个开源的计算机视觉库&#xff0c;可以处理图像和视频数据。它包含了超过2500个优化过的算法&#xff0c;用于对图像和视频进行处理&#xff0c;包括目标识别、面部识别、运动跟踪、立体视觉等。OpenCV支持多种编程语言&#xff0c;包括C、Python、Java等&#xff0c…

光谱图像论文浅读

文章目录 Hyperspectral Image Super-Resolution via Deep Spatiospectral Attention Convolutional Neural Networks Hyperspectral Image Super-Resolution via Deep Spatiospectral Attention Convolutional Neural Networks 通过上采样高光谱保留其光谱特征&#xff0c;采用…

在R中安装CmdStanR的步骤-R4.3.1-CmdStanR-0.6.1.900

报错未安装cmdstanr 安装包官网详细介绍&#xff1a; R Interface to CmdStan • cmdstanrhttps://mc-stan.org/cmdstanr/ 以下是在R中安装CmdStanR的步骤&#xff1a; 1. 首先&#xff0c;需要下载和安装C编译器 例如gcc。如果您已经安装了C编译器&#xff0c;则可以跳过此…

【数据结构--C语言】有序表算法及其应用

有序表是指其中的所有元素以递增或递减方式有序排列。为了简单&#xff0c;假设有序表以递增排列。 有序表的基本运算 InitLIst(&L)&#xff1a;初始化有序表LDestoryList(&L)&#xff1a;销毁有序表LListEmpty(L)&#xff1a;判断空表ListLength(L)&#xff1a;求有…

Mysql进阶-索引篇(上)

目录 索引概述 索引结构 数据结构 二叉树 红黑树 B-Tree BTree Hash 索引分类 聚集索引&二级索引 聚集索引选取规则: 具体结构 索引基础语法 SQL性能分析 SQL执行频率 慢查询日志 profile详情 explain 索引概述 介绍&#xff1a; 索引&#xff08; index &…

基于哈里斯鹰算法的无人机航迹规划-附代码

基于哈里斯鹰算法的无人机航迹规划 文章目录 基于哈里斯鹰算法的无人机航迹规划1.哈里斯鹰搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用哈里斯鹰算法来优化无人机航迹规划。 …

IOC课程整理-18 Spring注解

1. Spring 注解驱动编程发展历程 2. Spring 核心注解场景分类 3. Spring 注解编程模型 https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model 4. Spring 元注解&#xff08;Meta-Annotations&#xff09; 元注解&#xff08;Meta-A…

PostGreSQL:JSON|JSONB数据类型

JSON JSON 指的是 JavaScript 对象表示法&#xff08;JavaScript Object Notation&#xff09;JSON 是轻量级的文本数据交换格式JSON 独立于语言&#xff1a;JSON 使用 Javascript语法来描述数据对象&#xff0c;但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许…

什么是 CNN? 卷积神经网络? 怎么用 CNN 进行分类?(1)

先看卷积是啥&#xff0c;url: https://www.bilibili.com/video/BV1JX4y1K7Dr/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 下面这个式子就是卷积 看完了&#xff0c;感觉似懂非懂 下一个参考视频&#xff1a;https://www.y…

linux PELT算法中的load计算

滑窗平均的累加计算 权重y按滑窗距离衰减&#xff0c;y^32 0.5&#xff0c;也就是经历32个周期将衰减一半的权重&#xff0c;假设本周期值是&#xff36;&#xff0c;本周期的加权累加值为&#xff36;x&#xff0c;则&#xff1a; 一个完整周期是T&#xff0c;给一个基础值1…