Leetcode-数组篇 Day2

100 阅读2分钟

代码随想录算法训练营第二天| 977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II

  • 977.有序数组的平方

题目链接 视频讲解

本题的关键在于双指针,对于新手初步可以尝试暴力解法,先对数组每个元素取平方,然后快速排序,时间复杂度为 O(n+nlogn)O(n+nlogn).

下面着重介绍双指针法
数组其实是有序的,但是负数平方之后可能成为最大值。所以我们可以认为数组平方的最大值就在数组的两端,不可能是中间。此时就可以考虑双指针法,ii指向起始位置,jj指向终止位置。

如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j];
如果A[i] * A[i] >= A[j] * A[j] 那么result[k--] = A[i] * A[i];

此时时间复杂度为O(n)O(n).

总结: 此题的双指针法区别于 27.移除元素 ,27题的双指针从同一端出发,分别执行不同的任务。而这里的双指针从两端出发,通过比较和移动将最大的元素查找出来。注意双指针的灵活多样性。

  • 209.长度最小的子数组

题目链接 视频讲解

本题的关键是滑动窗口,最初的想法是暴力解法,利用两个for循环寻找符合条件的子数组,但时间复杂度为O(n2)O(n^2).

下面着重介绍滑动窗口
所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果
在暴力解法中,是一个for循环滑动窗口的起始位置,一个for循环为滑动窗口的终止位置,用两个for循环完成了一个不断搜索区间的过程。滑动窗口只用一个for循环这个循环的索引一定是滑动窗口的终止位置

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引
解题的关键在于 窗口的起始位置如何移动,如图所示:

图片.png

可以发现滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。

  • 59.螺旋矩阵II

题目链接 视频讲解

本题的关键在于转圈的逻辑以及区间定义。一定要遵循循环不变量原则,区间为左闭右开

图片.png

特别要注意的是对四个角的处理。