代码随想录算法训练营Day2 | 977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II、数组总结 | Python | 个人记录向

977.有序数组的平方

代码随想录:有序数组的平方
Leetcode:977.有序数组的平方

直接做题

要求时间复杂度为O(n),想过双指针,但习惯性就想到了指针同时动,又想空间复杂度能不能为O(1),想了一会没做出来,就看代码随想录了。

看文章

思路很简单,双指针不用同时动,哪个数的平方大,就存入结果数组,然后移动指针即可。空间复杂度为O(n)。

双指针

修改了一下自己的代码如下:

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        size = len(nums)
        left = 0
        right = size - 1
        res = [0] * size
        back = size - 1

        while left <= right:
            if (nums[left] * nums[left] > nums[right] * nums[right]):
                res[back] = nums[left] * nums[left]
                back -= 1
                left += 1
            else:
                res[back] = nums[right] * nums[right]
                back -= 1
                right -= 1
        
        return res

时间复杂度:O(n)
空间复杂度:O(n)

暴力求解

1. 暴力排序法
class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        for i in range(len(nums)):
            nums[i] *= nums[i]
        nums.sort()
        return nums
2. 暴力排序法+列表推导法
class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        return sorted(x*x for x in nums)

时间复杂度是 O(n + nlogn), 可以说是O(nlogn)的时间复杂度
空间复杂度:O(n)

209.长度最小的子数组

代码随想录:209.长度最小的子数组
Leetcode:209.长度最小的子数组

直接做题

使用滑动窗口法求解,但边界问题(或者说循环的终止条件)想了很久,即:right已经到数组末尾,但left还需继续往前滑动。
最终AC代码如下:

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        left, right = 0, 0
        size = len(nums)
        cur = 0
        cur_len = 0
        res = float('inf')
        flag = False
        while left < size:
            if cur < target and right < size:
                cur += nums[right]
                right += 1
                cur_len += 1
            else:
                if cur < target:
                    break
                flag = True
                res = min(res, cur_len)
                cur -= nums[left]
                left += 1
                cur_len -= 1
        if flag:
            return res
        else:
            return 0

看文章

暴力求解

时间复杂度:O(n^2)
空间复杂度:O(1)
通过两个for暴力搜索,在Leetcode上无法AC了。

滑动窗口

时间复杂度:O(n)
空间复杂度:O(1)
代码随想录与自己的做法差别在于,嵌套两个while,外层是right的移动,内层是left的移动。好像更好理解一点。

class Solution:
    def minSubArrayLen(self, s: int, nums: List[int]) -> int:
        l = len(nums)
        left = 0
        right = 0
        min_len = float('inf')
        cur_sum = 0 #当前的累加值
        
        while right < l:
            cur_sum += nums[right]
            
            while cur_sum >= s: # 当前累加值大于目标值
                min_len = min(min_len, right - left + 1)
                cur_sum -= nums[left]
                left += 1
            
            right += 1
        
        return min_len if min_len != float('inf') else 0

59. 螺旋矩阵II

代码随想录:59. 螺旋矩阵II
Leetcode:59. 螺旋矩阵II

直接做题

花了约40min,想过两种思路:

  1. 找规律,以n=4为例,发现填充3次,每次填充3个,然后再逐次递减,最后再补上剩余的数。但发现n=3时就不是这种规律了。
  2. 模拟贪吃蛇,一直往前走,如果撞到边界,或者前方有非初始化的数字,就换方向。方向的可选择集是右、下、左、上,依次切换。这个似乎可行,但实际实现有问题。

最后还是没做出来。

代码随想录解法

思路:

  1. 一共填充 n // 2 圈。每一圈的填充都以左闭右开的思路进行处理。
  2. 通过offset来处理每一圈的填充个数。
  3. 当n为奇数时,最后填充最中间的数。

体会:感觉还是要找到一些关键的、不受n影响的思路。
具体代码如下:

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        nums = [[0] * n for _ in range(n)]
        startx, starty = 0, 0               # 起始点
        loop, mid = n // 2, n // 2          # 迭代次数、n为奇数时,矩阵的中心点
        count = 1                           # 计数

        for offset in range(1, loop + 1) :      # 每循环一层偏移量加1,偏移量从1开始
            for i in range(starty, n - offset) :    # 从左至右,左闭右开
                nums[startx][i] = count
                count += 1
            for i in range(startx, n - offset) :    # 从上至下
                nums[i][n - offset] = count
                count += 1
            for i in range(n - offset, starty, -1) : # 从右至左
                nums[n - offset][i] = count
                count += 1
            for i in range(n - offset, startx, -1) : # 从下至上
                nums[i][starty] = count
                count += 1                
            startx += 1         # 更新起始点
            starty += 1

        if n % 2 != 0 :			# n为奇数时,填充中心点
            nums[mid][mid] = count 
        return nums

时间复杂度 O(n^2): 模拟遍历二维矩阵的时间
空间复杂度 O(1)

数组总结

代码随想录:数组总结

基本思路:

  1. 二分法
  2. 双指针法
  3. 滑动窗口
  4. 模拟行为

以往忽略的知识点小结

  • 双指针、滑动窗口的灵活使用
  • 模拟行为的规律归纳(可能需要经验)

个人体会

完成时间:3h。
心得:补充了更多规范化的思路,包括双指针、滑动窗口、模拟行为,但题目是无限的、思路也是无限的,不太可能记住所有规范化的思路,还是要保持通过自己思考直接求解的初心,然后再逐步引入规范化的思路,从而解决更多问题。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值