题目链接:力扣
文章讲解:代码随想录
视频讲解: 双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili
977.有序数组的平方
暴力排序法:
最直观的思路是先将所有元素平方,再排序。时间复杂度为排序的时间复杂度,即最快。
双指针法:
由于数组是有序的,平方之后最大的在两侧,最小的在中间。因此只需要比较两侧的值哪个大。因此可以用左右指针来解决,时间复杂度为。
P.S.: 其实刷题时候会有一个问题,就是什么时候用什么方式。有一些一目了然的解法,比如看到“有序”就自然想到二分查找,但是对于我这样的第一次接触双指针/滑动窗口的入门小白,在看到题目的时候并不能迅速做出准确判断,所以除了在被告知“用双指针”之后会写双指针之外,也应该总结遇到什么情况就应该马上考虑双指针/滑窗,或者总结使用双指针需要满足哪些条件。目前发现的一个条件是,左右两个指针都分别只往一个方向走,不能回头。希望自己之后做到更多的题目,可以不断更新这个总结。
209.长度最小的子数组
暴力双循环:
循环的索引是每个子序列的起始值,即遍历所有元素,使之作为子序列的开端,然后对于每一个开端,往后遍历找到所有的子序列,找到满足要求的长度最小的子序列长度。时间复杂度。
滑动窗口:
其实就是双指针,只是当我们关注的重点在左右指针中间的区间,而不是左右指针指向的元素本身时,可将这种方法称之为“滑动窗口(滑窗)”。滑动窗口通过不断调整子序列的起始位置和终止位置,用一个 for 循环完成两个 for 循环的工作。
如果使用一个for循环,那索引应该是子序列的终止位置(如果是遍历起始位置,那和暴力双循环并无差别)。本题中,滑窗内是子序列;如果窗口内的元素之和大于等于s了,则将滑窗起始位置向后移;如果窗口内的元素之和小于s了,则将滑窗的终止位置向后移。时间复杂度为。注意,虽然代码写的是一个 for 嵌套一个 while 或者两个 while,但每个元素只被操作了两次,(在滑动窗后进来操作一次,出去时操作一次),所以时间复杂度是 也就是,而非。
感觉用 python 写双指针/滑窗的时候,while 比 for 更好掌控。因为 while 里面可以自己手动调整滑窗两端的进展,而 for 更像是自动调节(每一轮就自动+1),因此写 for 的话要额外注意每一轮循环里完成什么事,确保该做的都做了,且顺序正确地做了,再进入下一轮循环。
59.螺旋矩阵II
题目链接:力扣
文章讲解:代码随想录
视频讲解:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili
模拟行为:
这题没有什么算法,主要是模拟计算机的行为,所以重点在于模拟的准确,要关注到细节。
1. 循环时,维持“二分查找”里的“不变量”原则,将填充区间定为左闭右开。
2. 整数 n --> 矩阵 n*n --> 循环多少层呢?可见若 n 为偶数,则循环 n/2 层;若 n 为奇数,则循环(n/2 + 1)层。为了保持一致性,我们永远循环 n/2 层,并在出循环后判断 n 是否为奇数,如果是,则填充中心位置为 n。