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

题目链接:力扣

文章讲解:代码随想录

视频讲解: 双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili

977.有序数组的平方

暴力排序法:

        最直观的思路是先将所有元素平方,再排序。时间复杂度为排序的时间复杂度,即最快O(nlogn)

双指针法:

        由于数组是有序的,平方之后最大的在两侧,最小的在中间。因此只需要比较两侧的值哪个大。因此可以用左右指针来解决,时间复杂度为O(n)

        P.S.: 其实刷题时候会有一个问题,就是什么时候用什么方式。有一些一目了然的解法,比如看到“有序”就自然想到二分查找,但是对于我这样的第一次接触双指针/滑动窗口的入门小白,在看到题目的时候并不能迅速做出准确判断,所以除了在被告知“用双指针”之后会写双指针之外,也应该总结遇到什么情况就应该马上考虑双指针/滑窗,或者总结使用双指针需要满足哪些条件。目前发现的一个条件是,左右两个指针都分别只往一个方向走,不能回头。希望自己之后做到更多的题目,可以不断更新这个总结。

209.长度最小的子数组

暴力双循环:

        循环的索引是每个子序列的起始值,即遍历所有元素,使之作为子序列的开端,然后对于每一个开端,往后遍历找到所有的子序列,找到满足要求的长度最小的子序列长度。时间复杂度O(n^2)

滑动窗口:

        其实就是双指针,只是当我们关注的重点在左右指针中间的区间,而不是左右指针指向的元素本身时,可将这种方法称之为“滑动窗口(滑窗)”。滑动窗口通过不断调整子序列的起始位置和终止位置,用一个 for 循环完成两个 for 循环的工作。

        如果使用一个for循环,那索引应该是子序列的终止位置(如果是遍历起始位置,那和暴力双循环并无差别)。本题中,滑窗内是子序列;如果窗口内的元素之和大于等于s了,则将滑窗起始位置向后移;如果窗口内的元素之和小于s了,则将滑窗的终止位置向后移。时间复杂度为O(n)。注意,虽然代码写的是一个 for 嵌套一个 while 或者两个 while,但每个元素只被操作了两次,(在滑动窗后进来操作一次,出去时操作一次),所以时间复杂度是 2*n 也就是O(n),而非O(n^2)

        感觉用 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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值