数据结构与算法---数组

题目列表

√ √

  1. https://leetcode-cn.com/problems/container-with-most-water/
  2. https://leetcode-cn.com/problems/move-zeroes/
  3. https://leetcode-cn.com/problems/climbing-stairs/
  4. https://leetcode-cn.com/problems/3sum/ (高频老题)
  5. https://leetcode-cn.com/problems/two-sum/
  6. https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/
  7. https://leetcode-cn.com/problems/rotate-array/
  8. https://leetcode-cn.com/problems/merge-sorted-array/

题目解析

  1. https://leetcode-cn.com/problems/container-with-most-water/
  2. https://leetcode-cn.com/problems/move-zeroes/
  3. https://leetcode-cn.com/problems/climbing-stairs/
  4. https://leetcode-cn.com/problems/3sum/ (高频老题)
  5. https://leetcode-cn.com/problems/two-sum/
  6. https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/
  7. https://leetcode-cn.com/problems/rotate-array/
  8. https://leetcode-cn.com/problems/merge-sorted-array/

数组

数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。

1.线性表

线性表 就是数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。其实除了数组,链表、队列、栈等也是线性表结构
在这里插入图片描述
非线性表,比如二叉树、堆、图等。之所以叫非线性,是因为,在非线性表中,数据之间并不是简单的前后关系
在这里插入图片描述

2.连续的内存空间和相同的数据类型

正是因为这两个限制,它才有了一个堪称“杀手锏”的特性:“随机访问
有利就有弊,这两个限制也让数组的很多操作变得非常低效,比如要想在数组中删除、插入一个数据,为了保证连续性,就需要做大量的数据搬移工作。

实现随机访问

通过指针和元素的size

a[i]_address = base_address + i * data_type_size

在这里插入图片描述

查找

链表适合插入、删除,时间复杂度 O(1)
错误说法:数组适合查找,查找时间复杂度为 O(1)
正确说法:数组是适合查找操作,但是查找的时间复杂度并不为 O(1)。即便是排好序的数组,你用二分查找,时间复杂度也是 O(logn)。所以,正确的表述应该是,数组支持随机访问,根据下标随机访问的时间复杂度为 O(1)。

插入

最好时间复杂度: 插入末尾 O(1)
最差时间复杂度: 插入开头 O(n)
平均时间复杂度: (1 + 2 +…+n)/n = O(n)

特殊情况:当数组是一个不按顺序,类似一个集合,可直接将待插入位置元素放到数组末尾,然后将待插入元素插入即可,时间复杂度O(1)=====>这个思想在快排中用到
在这里插入图片描述

删除

删除后要将后面元素前移
最好时间复杂度: 删除末尾 O(1)
最差时间复杂度: 删除开头 O(n)
平均时间复杂度: (1 + 2 +…+n)/n = O(n)

特殊情况:
在这里插入图片描述
为了避免 d,e,f,g,h 这几个数据会被搬移三次,我们可以先记录下已经删除的数据。每次的删除操作并不是真正地搬移数据,只是记录数据已经被删除。当数组没有更多空间存储数据时,我们再触发执行一次真正的删除操作,这样就大大减少了删除操作导致的数据搬移。
=====>JVM 标记清除垃圾回收算法的核心思想
=====>生活中,我们扔进屋里垃圾桶的垃圾,并没有消失,只是被 ‘‘标记’’ 成了垃圾,
只有垃圾桶塞满时,才会清理垃圾桶。再次存放垃圾

数组越界问题

c语言数组越界
java中有数组越界检测,越界报错java.lang.ArrayIndexOutOfBoundsException

容器能否完全代替数组

很多语言都提供了容器类,比如 Java 中的 ArrayList、C++ STL 中的 vector。在项目开发中,什么时候适合用数组,什么时候适合用容器呢?
支持动态扩容
每次存储空间不够的时候,它都会将空间自动扩容为 1.5 倍大小。
因为扩容操作涉及内存申请和数据搬移,是比较耗时的。所以,如果事先能确定需要存储的数据大小,最好在创建 ArrayList 的时候事先指定数据大小。

有些时候,用数组会更合适些
1.Java ArrayList 无法存储基本类型,比如 int、long,需要封装为 Integer、Long 类,而 Autoboxing、Unboxing 则有一定的性能消耗,所以如果特别关注性能,或者希望使用基本类型,就可以选用数组。
2. 如果数据大小事先已知,并且对数据的操作非常简单,用不到 ArrayList 提供的大部分方法,也可以直接使用数组。
3. 还有一个是我个人的喜好,当要表示多维数组时,用数组往往会更加直观。比如 Object[][] array;而用容器的话则需要这样定义:ArrayList > array。

为什么大多数编程语言中,数组要从 0 开始编号,而不是从 1 开始呢?

在这里插入图片描述

题目

  1. https://leetcode-cn.com/problems/container-with-most-water/
  2. https://leetcode-cn.com/problems/move-zeroes/
  3. https://leetcode.com/problems/climbing-stairs/
  4. https://leetcode-cn.com/problems/3sum/ (高频老题)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值