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

文章介绍了如何使用双指针策略解决LeetCode上的三个问题:有序数组的平方、长度最小的子数组和螺旋矩阵II。主要涉及数组操作、动态计算和循环结构的应用。
摘要由CSDN通过智能技术生成

977. 有序数组的平方

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep
状态:思路较为清晰。

思路

绝对值越大的数平方越大。因此,对于有序数组而言,平方大的数一定在数组的两边。因此可以使用两个指针从两侧向中间遍历数组。将每一次循环得到的数从后向前插入结果数组,即可得到从小到大排列的平方数组。

代码:

class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        left = 0
        right = len(nums)-1
        point = right
        res = [0.0]*len(nums)
        while left <= right:
            if abs(nums[left])<abs(nums[right]):
                res[point]=nums[right]**2
                right-=1
            else:
                res[point]=nums[left]**2
                left+=1
            point-=1
        return res

209.长度最小的子数组

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
文章讲解:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE
状态:理解滑动窗口,本题要想清楚是使用while还是使用if。

思路

本题的主要思路也是使用双指针来维护滑动窗口。外层循环用来遍历整个数组,内层两个循环,第一层的条件为While sum < target, 循环目的是改变右边区间,使滑动窗口范围内的总和大于target,接下来第二个循环用于改变左区间,寻找在满足sum>=target条件时,最小的窗口长度。

接下来对思路进行优化,发现只用两个循环就可以实现。第一层内循环其实没必要,外层循环做的事就是每一次将滑动窗口向右移动一个位置。代码如下:

代码:

版本一:

class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        lens = len(nums)
        if lens == 0:
            return 0
        sum = 0
        slow = 0
        fast = 0
        resLen = float('inf')
        
        while fast<lens:
            while sum < target and fast < lens:
                sum+=nums[fast]
                fast+=1
            while sum >= target:
                resLen=min(resLen,fast-slow)
                sum-=nums[slow]
                slow+=1
        return 0 if resLen==float('inf') else resLen

版本二

class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        lens = len(nums)
        if lens == 0:
            return 0
        sum = 0
        slow = 0
        fast = 0
        resLen = float('inf')
        
        while fast<lens:
            sum+=nums[fast]
            while sum >= target:
                resLen=min(resLen,fast-slow+1)
                sum-=nums[slow]
                slow+=1
            fast+=1
        return 0 if resLen==float('inf') else resLen

59. 螺旋矩阵II

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/
状态:思路清晰,找准循环不变量。

思路

本题我的思路是按照圈数来循环。

  • 对于奇数行,圈数为n/2,再填充最中间的元素。
  • 对于偶数行,圈数为n/2.

大循环用与遍历每一圈,内层用4个小循环用于模拟上下左右的边,循环的关键在于找到循环不变量,确保每个边都是左闭右开。

代码

class Solution(object):
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        cycle = n//2
        res = [[0] * n for _ in range(n)]
        incr=1
        for i in range(cycle):
            for top in range(i,n-i-1):
                res[i][top]=incr
                incr+=1
            for right in range(i,n-i-1):
                res[right][n-i-1]=incr
                incr+=1
            for bot in range(n-i-1,i,-1):
                res[n-i-1][bot]=incr
                incr+=1
            for left in range(n-i-1,i,-1):
                res[left][i]=incr
                incr+=1
        if n%2==1:
            res[n//2][n//2]=n**2
        return res
  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值