代码随想录算法训练营第二天

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

977.有序数组的平方

题目链接:有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

知道这个题要用双指针但一时半会儿没什么感觉,所以就先暴力拆解了

暴力解题

是非常单纯的一个个平方然后再排序,顺便复习一下两种sort的内置函数。

class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        l = []
        for i in nums:
            l.append(i**2)

        #l.sort()
        #return l
        return sorted(l)

双指针

非常惭愧实在虽然理解了双指针但对这道题还是没什么思路,所以还是去看图解了。
图解
这道题特别的地方在于,平方之后他的大小其实是两边大然后往中间减小的,所以用双指针一根在头一根在尾比较两个位置的元素大小之后将大的那个放入新数组的最后一位,这样从后往前(从大到小)就可以找到重新排列的序列。

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

写赋值给新数组的时候我写的是数组合并的形式,也可以先定义一个
l = [-1]*len(nums)然后直接从后往前赋值。

209.长度最小的子数组

题目链接:长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

以前做过一次用的是暴力解法,跑是可以跑,最后超时了,所以就不再写一遍了,这里直接开始滑动窗口。

滑动窗口

滑动窗口其实类似双指针,不过双指针的重点在指针上而滑动窗口的重点在指针之间的区间上。用上面的例子来演示。
nums = [2,3,1,2,4,3],left和right一开始都指向2。
滑动right最后可以得到一个符合条件的[2,3,1,2](加起来大于7)更新一下,然后滑动left到nums[1]也就是3,注意这个时候的窗口[3,1,2]也要考虑是不是满足条件,满足的话也要更新一下,然后接着滑动right指针用来获得中间的窗口是否符合条件。
写了两个版本的滑动窗口,应该是因为每次都记录了每个list导致超时。

class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        left = 0
        right = 0
        if sum(nums) < target:
            return 0
        else:
            s = len(nums)

        while right <= len(nums):
            l = nums[left:right]
            print(l)
            #print(l)
            if sum(l) < target:
                right += 1
            else:
                s = min(len(l),s)
                left += 1
        return s

这个是把left的操作打包进了while一起做了,但还是超时了。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        i = 0
        if sum(nums) < target:
            return 0
        else:
            s = len(nums)

        for j in range(len(nums)):
            l = nums[i:(j+1)]
            #print(l)
            while sum(l) >= target:
                s = min(len(l),s)
                i += 1
                l = nums[i:(j+1)]
        return s

如果不记录每个list是什么,只记录sum的大小的话,不打包循环了是没有办法做得,所以最后改成了这样。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        i = 0
        sums = 0
        if sum(nums) < target:
            return 0
        else:
            s = len(nums)

        for j in range(len(nums)):
            sums += nums[j]
            while sums >= target:
                s = min(j-i+1,s)
                sums -= nums[i]
                i += 1
        return s

滑动窗口当left指针开始滑动的时候一定要记得打包了做循环不然管不过来。
(其实很久以前已经错过一次了回来还接着错。。。)

59.螺旋矩阵II

题目链接:螺旋矩阵II
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

输入:n = 3
1,2,3
8,9,4
7,6,5
输出:[[1,2,3],[8,9,4],[7,6,5]]

这题算的眼睛都要花了,这个循环是以圈为单位的,以n=5为例,图画在下面了。
n=5的情况
红色的是第一圈,橙色的是第二圈,每行每列都是左闭右开,在填入的时候也要注意。

class Solution(object):
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        ans = [[-1]*n for _ in range(n)]
        nums = range(1,(n**2+1))
        ans[:][0] = [1,2,3]
        #print(ans)
        start = 0
        for i in range(int(n/2)):
            ans[i][i:(n-1-i)] = nums[start:(start+(n-(2*i+1)))]
            #print(nums[start:(start+(n-(2*i+1)))])
            for j in range(i,n-1-i):
                ans[j][-i-1] = nums[start+(n-(2*i+1))+j-i]
            #print(nums[(start+(n-(2*i+1))):(start+2*(n-(2*i+1)))])
            #ans[-i-1][(i+1):(n-i)] = nums[(start+2*(n-(2*i+1))):(start+3*(n-(2*i+1)))]
            #print(nums[(start+2*(n-(2*i+1))):(start+3*(n-(2*i+1)))])
            for j in range((i+1),(n-i)):
                ans[-i-1][n-j] = nums[start+2*(n-(2*i+1))+j-i-1]
                ans[n-j][i] = nums[start+3*(n-(2*i+1))+j-i-1]
            #print(nums[(start+3*(n-(2*i+1))):(start+4*(n-(2*i+1)))])
            start += 4*(n-(2*i+1))

        if n%2 == 1:
            ans[int(n/2)][int(n/2)] = n**2

        return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值