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 排列

posted @ 2020-07-01 09:49  不写诗的诗人小安  阅读(186)  评论(0编辑  收藏  举报