代码随想录|数组(2)

本文介绍了如何使用滑动窗口法解决LeetCode问题209(长度最小的子数组),降低时间复杂度至O(n)。同时,对LeetCode问题59(螺旋矩阵II)的解题思路进行了分析,强调了循环条件和分层处理的重要性。

数组之滑动窗口法及模拟过程

209. 长度最小的子数组

Leetcode209

此题可使用暴力解法,即先记录子数组开头位置并进行循环,再对于每个开头元素找到符合要求的最小子数组,并记录长度。

def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        left = 0
        re = []
        
        while left < len(nums):
            
            add = nums[left]
            right = left + 1
            while add < target and right < len(nums):
                add = add + nums[right]
                right = right + 1
            if add >= target:
                re.append(right-left)
            else:
                re.append(0)
            left = left + 1
        
        if sum(re) == 0:
            return 0
        else:
            return min([ele for ele in re if ele>0])

此暴力算法仍不够简洁,按题意只需要一个整数型变量re记录符合要求的子数组长度,无需开辟一个数组re。

但暴力解法的时间复杂度为O(n^2),会显示超时,可使用滑动窗口法使得时间复杂度降为O(n)

滑动窗口法可以理解为特殊的双指针法,两个指针分别指向子数组的开头和末尾。特别的是在滑动窗口法中,只对指向子数组末尾的指针进行循环,若窗口内的元素之和大于或等于目标值,则指向子数组开头的指针向前移动。

这种方法中指向开头的指针不会重复遍历数组,降低了时间复杂度。

def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        right = 0
        left = 0
        count = inf
        add = 0
        while right <= len(nums) - 1:
            add = add + nums[right]
            while add >= target:
                if left == right:
                    return 1
                else:
                  
                    if count > right - left + 1:
                        count =  right - left + 1
                    add = add - nums[left]
                    left = left + 1
            right = right + 1

        if count == inf:
            return 0
        else:
            return count

59 . 螺旋矩阵Ⅱ

Leetcode59

一开始对此题毫无思路,看了题解后发现是自己无法梳理清楚循环的条件以及不知道怎么对循环分层和分段。

此题中转一圈可视为一层,每一层的共同点是该层元素坐标中的不变量(横坐标或纵坐标)相同,且循环的元素和层数相关。在每一层中,根据不变量需要将其分为四段,此处的分法要保证每层分割的规则相同,可类比二分法中对循环条件的处理。

 def generateMatrix(self, n: int) -> List[List[int]]:
        num = 1
        re =  [[j for j in range(0,n)]for i in range(0,n)]

        for round in range(0,n//2):
            x = round
            for y in range(round,n-1-round):
                re[x][y] = num
                num = num + 1
            
            y = n-1-round
            for x in range(round,n-1-round):
                re[x][y] = num
                num = num + 1
            
            x = n-1-round
            for y in reversed(range(round+1,n-round)):
                re[x][y] = num
                num = num + 1
            
            y = round
            for x in reversed(range(round+1,n-round)):
                re[x][y] = num
                num = num + 1

        if n%2 == 1:
            re[n//2][n//2] = n**2
        
        return re

# 注意一共转n//2个round
# 每个for循环均为循环不变量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值