主题:数组
1.两数之和
tag:数组;哈希表
(1)C++中的map和unordered_map区别
头文件 | 内部实现 | 优点 | 缺点 | 用途 | |
---|---|---|---|---|---|
map | #include < map > | 红黑树(二叉搜索树) | 有序 | 空间占用高 | 需排序场景 |
unordered_map | #include < unordered_map > | 哈希表 | 查找速度快 | 建立费时,更耗内存 |
注:
- 二叉查找树、二叉排序树:特点就是左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值)存储的,使用中序遍历可将键值按照从小到大遍历出来。但空间占用高
- unordered_map的用法和map是一样的,提供insert,size,count等操作,元素以pair类型存储
2.寻找两个正序数组的中位数(4)
tag:数组;二分法
(1)巧用INT_MAX 及INT_MIN
int nums_im1 = (i == 0 ? INT_MIN : nums1[i - 1]);
int nums_i = (i == m ? INT_MAX : nums1[i]);
int nums_jm1 = (j == 0 ? INT_MIN : nums2[j - 1]);
int nums_j = (j == n ? INT_MAX : nums2[j]);
(2)C++中vector、array与数组
- array和vector都对下标运算符[ ]进行了重载
- 三者存储空间都是连续的
- 数组是不安全的,其他两种安全
- array 定义时必须定义数组的元素个数,且只能包含整型字面值常量,枚举常量或者用常量表达式初始化的整型const对象,非const变量以及需要到运行阶段才知道其值的const变量都不能用来定义数组的维度,而vector 不需要
- vector定义后的空间可再增减,array不可以
- array和vector不同,不能用另一个数组初始化,也不能将一个数组赋值给另一个数组
.
3.寻找两个正序数组的中位数(11)
tag:数组,双指针
(1)通过移动指针来缩减问题规模
4.三数之和(15)
tag:数组,排序+双指针
(1)C++的vector中sort为快排
5.最接近的三数之和(16)
tag:数组,双指针
6.四数之和(18)
tag:数组,双指针
7.删除排序数组中的重复项(26)
tag:数组,双指针
8.移除元素(27)
tag:数组,双指针
9.下一个排列(31)
tag:数组,双指针
(1)对于有序数组,通过reverse来调整升降序列
(2)算法值得思考
10.搜索旋转排序数组(33)
tag:数组,二分查找
11.在排序数组中查找元素的第一个和最后一个位置(35)
tag:数组,双向二分
12.搜索插入位置(35)
tag:数组,二分
(1)要根据情况将< = >三种符号进行二分分割,比如在不寻找等于的时候寻找第一个大于等于的数字或小于等于的数字
12.组合总和(39)
tag:数组,搜索回溯
(1)寻找所有可行解的题,都可以尝试用「搜索回溯」
(2)回溯法从问题本身出发,寻找可能实现的所有情况。和穷举法的思想相近,不同在于穷举法是将所有的情况都列举出来以后再一一筛选,而回溯法在列举过程如果发现当前情况根本不可能存在,就停止后续的所有工作,返回上一步进行新的尝试。
递归是从问题的结果出发,例如求 n!,要想知道 n!的结果,就需要知道 n*(n-1)! 的结果,而要想知道 (n-1)! 结果,就需要提前知道 (n-1)*(n-2)!。这样不断地向自己提问,不断地调用自己的思想就是递归。
(3)emplace_back() 和 push_back() 的区别:底层实现的机制不同。push_back() 向容器尾部添加元素时,会先创建元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
13.组合总和 II(40)
tag:数组,搜索回溯
14.缺失的第一个正数(41)
tag:数组,本地哈希
15.接雨水(42)
tag:数组,动态规划
(1)idea
(2)动态规划的空间优化,本题采用漂亮的双指针法
(3)栈
16.跳跃游戏 II(45)
tag:数组,贪心
(1)贪心:探寻边界
17.旋转图像(48)
tag:数组,数学-矩阵
(1)带入符号推导
(2)积极利用矩阵翻转
18.最大子序和(53)
tag:数组,动态规划,分治,线段树
(1)分治方法更为灵活,适用范围更广