> 提示:DDU,供自己复习使用。欢迎大家前来讨论~
数组
数组的复习
一、数组理论基础
数组是存放在连续内存空间上的相同类型数据的集合。
细节注意:
- 数组的下标都是从0开始。
- 数组内存空间的地址是连续的。(因为连续,所以在删除和插入的时候,要依次移动其他的元素)
vector 与数组的不同点:
- 大小可变性:std::vector 可以动态地增加或减少其大小,而数组的大小在创建时确定,之后不能改变。
- 内存管理:std::vector 负责其内部数组的内存分配和释放,而数组需要程序员手动管理内存(除非使用自动或动态存储期)。
- 功能丰富:std::vector 提供了丰富的成员函数和运算符来操作容器,例如 push_back(), pop_back(), resize(), capacity(), rbegin(), rend() 等,而数组则没有这些功能。
- 迭代器:std::vector 支持迭代器,可以与泛型算法一起使用,而传统的 C 风格数组则不支持迭代器。
二维数组在内存的空间地址是连续的么?
二维数组,元素在内存中通常是按行优先(row-major order)顺序排列的,这意味着数组的元素在内存中是连续存储的,但是这种连续性是按行来组织的
二、数组的经典题目
-
二分法:数组有序并且元素不重复。
- 循环不变量原则
- 暴力解法时间复杂度:O(n)
- 二分法时间复杂度:O(logn)
-
双指针法:(快慢指针法):通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。一个用来读,一个用来写。
-
暴力解法时间复杂度:O(n^2)
-
双指针时间复杂度:O(n)
-
数组在内存中是连续的地址空间,不能释放单一元素,如果要释放,就是全释放(程序运行结束,回收内存栈空间)。
-
C++中vector和array的区别一定要弄清楚,vector的底层实现是array,封装后使用更友好。
-
-
滑动窗口:
- 滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。
- 时间复杂度:O(n):
不要以为for里放一个while就以为是O(n^2)啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。
-
模拟行为
循环不变量原则
-
前缀和
数组求区间和。
前缀和的思路其实很简单,但非常实用,如果没接触过的录友,也很难想到这个解法维度,所以 这是开阔思路 而难度又不高的好题。
总结
从二分法到双指针,从滑动窗口到螺旋矩阵。