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

977.有序数组的平方

题目链接
先无视有序,直接暴力平方后用sort函数排序

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        ans = []
        for i in nums:
            ans.append(i*i)
        ans.sort()
        return ans

复杂度O(n)+O(nlogn) python的sort函数复杂度
再尝试利用有序特性,使用双指针法

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        left = 0
        right = len(nums) - 1
        ans = []
        while left <= right:
            if abs(nums[left]) > abs(nums[right]):
                ans.append(nums[left]**2)
                left += 1
            else:
                ans.append(nums[right]**2)
                right -= 1
        return ans[::-1]

最大的一定在最左边或最右边,如此依次访问直到左右指针相遇,但是最后需要反序输出
复杂度O(n)
但是提交之后居然比前面一个代码时间还长,就离谱

209 长度最小的子数组

题目链接
仍然先尝试暴力解法

    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        ans = []
        for i in range(len(nums)):
            sum = 0
            num = 0
            for j in range(i, len(nums)):
                sum += nums[j]
                num += 1
                if sum >= target:
                    ans.append(num)
                    break
        if len(ans) != 0:
            return min(ans)
        else:
            return 0

直接两重循环,一重循环从数组的每个位置开始累加,直到大于等于target,记录累加个数,如此访问到数组末尾,取记录到的个数最小值,复杂度O(n^2),遇到一个超大数组后超时了
下面尝试滑动窗口法:
遇到了困难,只知道是左右指针不断移动,大于等于target则左指针加,和减少,但是实现不出来,看了示意图我对滑动窗口的理解是没错的,但是实现有困难。。
看了解答后发现原来仍然有两层循环

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        left = 0
        sum = 0
        ans = len(nums) + 1
        num = 0
        for right in range(len(nums)):
            sum += nums[right]
            while sum >= target:
                num = right - left + 1
                if num < ans:
                    ans = num
                sum -= nums[left]
                left += 1
        if ans == len(nums) + 1:
            return 0
        else:
            return ans

关键在于循环累加,超过target则从左边开始减,减到小于target
有尝试过用一个while循环,但没有成功

59 螺旋矩阵

题目链接
这题挺难的,之前做过一次没做出来,看了一遍答案自己写了一遍,现在再做还是不会。。没办法再看一遍答案再写吧。。

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        nums = [i for i in range(1,n*n+1)]
        res = [[0]*n for i in range(n)]
        loop = int(n/2)
        num = 1
        for l in range(loop):
            i = l
            for j in range(l, n-l-1):
                res[i][j] = num
                num += 1
            j = n-l-1
            for i in range(l,n-l-1):
                res[i][j] = num
                num += 1
            i = n-l-1
            for j in range(n-l-1,l,-1):
                res[i][j] = num
                num += 1
            j = l
            for i in range(n-l-1,l,-1):
                res[i][j] = num
                num += 1
        if n%2 != 0:
            res[int(n/2)][int(n/2)] = n**2
        return res

自己写的时候循环就不对,这里的循环重点是loop,而不应该循环要放入的数字

总结

关于数组,有一些技巧是需要掌握的:双指针法,滑动窗口法
但更重要的是循环不变量原则,因为我感觉我有时候怎么写都报错,逻辑不清一团乱麻就是边界条件找不准,或者是循环的切入角度不对。。

你可能感兴趣的:(代码随想录刷题记录,算法,leetcode,矩阵)