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

977.有序数组平方根

题目连接:977.有序数组平方根

思路:数组其实是有序的,只不过负数平方之后可能成为最大数了。那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。此时可以考虑双指针法了,i指向起始位置,j指向终止位置。定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。

  • 如果A[i] * A[i] < A[j] * A[j] 那么result[k- -] = A[j] * A[j]; 。
  • 如果A[i] * A[i] >= A[j] * A[j] 那么result[k --] = A[i] * A[i]; 。

代码如下:

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        left, right, i = 0, len(nums) - 1, len(nums) - 1
        res = [float('inf')] * len(nums) #float('inf')表示列表元素为正无穷大
        while left < right:
            if nums[left] ** 2 < nums[right] ** 2:
                res[i] = nums[right] ** 2
                right -= 1  # 右指针向左移
            else:
                res[i] = nums[left] ** 2
                left += 1   #左指针向右移
            i -= 1  # 存放结果的数组向前移
        return res
  • 时间复杂度O(n)
  • 空间复杂度O(1)

学习时长
20分钟

209.长度最小的子数组

题目连接:209.长度最小的子数组

思路:这道题目暴力解法当然是 两个for循环,然后不断的寻找符合条件的子序列,如果用滑动窗口来解决,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。本题要实现滑动窗口移动要确定以下三个点:

  • 窗口的值满足其和 ≥ s
  • 如果当前窗口的值大于s了,窗口起始位置就要向前移动了(也就是该缩小了)
  • 如果当前窗口的值不大于s了,窗口结束位置就要向前移动了,窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

代码如下:

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        l = len(nums)
        cur_sum = 0
        cur_min = float('inf')
        i = 0
        for j in range(l):
            cur_sum += nums[j]
            while cur_sum >= target:
                cur_min = min(cur_min, j - i + 1)
                cur_sum -= nums[i]
                i+=1
        return cur_min if cur_min != float('inf') else 0
  • 时间复杂度O(n)
  • 空间复杂度O(1)

注意:不要以为for里放一个while就以为是O(n^2), 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。

学习时长
20分钟

59.螺旋矩阵II

题目连接:59.螺旋矩阵II

思路:模拟顺时针画矩阵的过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

由外向内一圈一圈这么画下去,由外向内一圈一圈这么画下去,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。
代码如下:

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        nums = [[0]*n for _ in range(n)]
        startx = 0
        starty = 0
        count = 1
        loop = n//2
        mid = n//2
        for offset in range(1,loop+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:
            nums[mid][mid] = count
        return nums
  • 时间复杂度 O(n^2)
  • 空间复杂度 O(1)

学习时长
1个小时

今日小结

今天的题目前两道还是比较简单的,学会双指针和滑动窗口思路,很快就把代码写出来了,螺旋矩阵看了蛮久的,理清了思路,很快也写出来了。脑子已经慢慢好使,今后继续加油!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值