LeetCode系列之数组专题
1. 数组题目概述
https://leetcode-cn.com/tag/array/
以下仅挑选若干个仅有“数组”标签的题目,如同时有“数组”、“动态规划”的标签,将纳入“动态规划”专题。
2. 典型题目
2.1 顺时针旋转 n x n 矩阵
https://leetcode-cn.com/problems/rotate-image/
矩阵变换方法,可以分为两步:
转置矩阵
void transposite(vector<vector<int>>& matrix) { int n = matrix.size(); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { std::swap(matrix[i][j], matrix[j][i]); } } }
左右翻转矩阵
void reverse(vector<vector<int>>& matrix) { for (auto& line : matrix) { std::reverse(line.begin(), line.end()); } }
时间复杂度O(N2);空间复杂度O(1)。
问题:如何证明顺时针旋转90度和“转置+翻转”是等价的?
2.2 下一个排列
https://leetcode-cn.com/problems/next-permutation/
一遍扫描法,分为三步:
找递增数对、交换、翻转
// TODO
时间复杂度O(N);空间复杂度O(1)。
2.3 加一
https://leetcode-cn.com/problems/plus-one/
// TODO
时间复杂度最差O(N),最好O(1);空间复杂度O(1)。
2.4 找到所有数组中消失的数字
https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/
巧妙利用题目中“1 ≤ a[i] ≤ n”的条件,可以给出空间复杂度为O(1)的解法。
条件可以变换成“0 ≤ a[i]-1 ≤ n-1”,以便和数组下标进行对应。用数组内数值的正负代表是否出现过,说实话,有点“鸡贼”。
// TODO
时间复杂度O(N);空间复杂度O(1)。
2.5 统计位数为偶数的数字
https://leetcode-cn.com/problems/find-numbers-with-even-number-of-digits/
这里值得一提的是判断位数为偶数的方法
// 官方题解给出的判断方法 if (to_string(num).size() % 2 == 0) {
...
}
时间复杂度O(N),N是数组长度,假设to_string的时间复杂度是O(1);空间复杂度O(1)。
2.6 最大连续1的个数
https://leetcode-cn.com/problems/max-consecutive-ones/
简单题,一次遍历,略过了。
时间复杂度O(N);空间复杂度O(1)。
2.7 最短无序连续子数组
https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/
TBD
2.8 数组中重复的数据
https://leetcode-cn.com/problems/find-all-duplicates-in-an-array/
与2.4题目类似,看到“1 ≤ a[i] ≤ n”的已知条件,要考虑利用索引。
TBD
2.9 提莫攻击
https://leetcode-cn.com/problems/teemo-attacking/
判断时间序列间隔和给定duration的大小,对二者的较小值进行累加。
int findPoisonedDuration(vector<int>& timeSeries, int duration) { if (timeSeries.empty()) return 0; int total = duration; for (int i = 1; i < timeSeries.size(); i++) { total += std::min(timeSeries[i] - timeSeries[i-1], duration); } return total; }
时间复杂度O(N);空间复杂度O(1)。
2.10 旋转数组
https://leetcode-cn.com/problems/rotate-array/
反转方法实用,且效率高!
void rotate(vector<int>& nums, int k) { int step = k % nums.size(); reverse(nums.begin(), nums.end()); reverse(nums.begin(), nums.begin() + step); reverse(nums.begin() + step, nums.end()); }
时间复杂度O(N);空间复杂度O(1)。
3. 总结
做算法,背单词
transposite 转置
reverse 翻转
permutation 排列