代码随想录算法训练营第二天 | 977.Squares of a Sorted Array ,209.Minimum Size Subarray Sum,59.Spiral Matrix II

文章讨论了在解决编程问题时如何利用双指针技巧,如暴力法、双指针排序和滑动窗口,以提高算法效率。重点介绍了如何通过空间换时间减少复杂度,以及在特定问题中的应用实例,如SquaresOfASortedArray和MinimumSizeSubarraySum。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:无意发现Leetcode有时间和控件复杂度分析,好耶!

977.Squares of a Sorted Array | Link

核心词:双指针

方法一:暴力(自己想的)

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        nums2 = []
        for e in nums:
            nums2.append(e*e)
        nums2.sort()
        return nums2
# 暴力
# Time: O(nlogn)

方法二:双指针(也是自己想的) 

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        left = 0
        right = len(nums) - 1
        result = [None]*len(nums)
        back_index = len(nums) - 1

        while(left <= right):
            if abs(nums[left]) <= abs(nums[right]):
                result[back_index] = nums[right]*nums[right]
                back_index -= 1
                right -= 1
            else:
                result[back_index] = nums[left]*nums[left]
                back_index -= 1
                left += 1
        return result
# Time: O(n)
# 自己想的双指针
  • 我首先用了暴力方法,对原数组平方以后,调用排序函数。复杂度O(nlogn).
  • 推荐的解法是双指针
  • 本题引入新的结果空间result,属于是“空间换时间”
  • 本题题干说,“non-decreasing order”,这类有序的条件必有用。考虑下双指针。
  • 注意创建空的固定长度list方法:result = [None]*len(nums)
  • 2504刷题,通过本题和上一题,我发现一个自己的思考缺陷,就是一旦涉及双指针题目,只考虑用while循环,但while循环需要(在不止一处加上)对越界的判断,很麻烦。其实用for循环会很简单。

209.Minimum Size Subarray Sum | Link

Key Words: 滑动窗口(本质也是双指针),双循环但复杂度O(n)

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        i = 0
        sum = 0
        result = len(nums) + 1

        for j in range(len(nums)):
            sum += nums[j]
            while sum >= target:
                result = min(j-i+1,result)
                sum -= nums[i]
                i += 1
        
        if result == len(nums) + 1:
            return 0
        else:
            return result
# 双指针法
# 看似两个循环,但实际满打满算只循环2轮,即O(2n) = O(n)
  • 遍历的j代表启示指针or终点指针?只能是终点,不然与暴力解一样了。
  • 循环条件中,若i j没有相等的话,则循环最后i j一样的那个元素丢失(未处理)。
  • 精彩!两个for,时间复杂度居然是O(n):他两个指针满打满算一共就跑了2n次啊,但是你用暴力解法每一个i就要重新跑一次j,自然就是n的平方
  • [网友] 怎么说呢,滑动窗口本质上也是一种双指针法,是在充分理解题目的情况下,暴力算法的一种简化。
    这道题之所以可以使用滑动窗口,很重要的一个原因是,在移动终止位置的时候,初始位置是不可逆的,初始位置只可能往后移动,而不用每次都从第零个元素开始。
    • 这里”初始位置“指的是:终止位置(终止指针)的每次进行循环前开始的位置。
    • 所有双指针法,都是充分利用题目的一个隐藏的特征,来对暴力算法的一种简化
  • 视频中,老师说result初始值设为MAX,其实不必,设为len(nums) + 1即可
  • 最后return可以用Python的三目运算符简化:
    return 0 if result == len(nums) + 1 else result

59.Spiral Matrix II | Link

Key Points: 循环不变量原则,循环的边界条件

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        nums = [[0] * n for _ in range(n)]
        startx,starty = 0,0
        offset = 1
        val = 1
        loop = n // 2

        for offset in range(1, loop + 1) : 

            for j in range(starty,n-offset):
                nums[startx][j] = val
                val += 1
            
            for i in range(startx, n-offset):
                nums[i][n-offset] = val
                val += 1
            
            for j in range(n-offset,starty, -1):
                nums[n-offset][j] = val
                val += 1
            
            for i in range(n-offset,startx, -1):
                nums[i][starty] = val
                val += 1
            
            startx += 1
            starty += 1

            
        if n%2 == 1:
            nums[n//2][n//2] = val
    
        return nums
        
  • 本题每次做,每次都做不成功。中途看了3次老师的代码。
  • 循环不变量 原则。该方法可以简化代码/边界条件。本题中,循环==转一圈,不变量==对边界的处理方式(指开闭)
  • 我最初的想法都是对的,除了对奇数行的处理:单拎出来赋值。
  • 本题必须画图分析。
  • 一些Python语法不熟悉:
    • 创建值为0的 n*n list:
      nums = [[0] * n for _ in range(n)]
  •  range从大到小,要有-1:
    range(10,1, -1) 

数组总结关键点:

  • 数组是存放在连续内存空间上的相同类型数据的集合。
  • 因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。
  • Java的二维数组在内存中不是 3*4 的连续地址空间,而是四条连续的地址空间组成!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值