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

977.有序数组的平方

题目链接:. - 力扣(LeetCode)

文章讲解:代码随想录

视频讲解: 双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili

1.暴力解法 

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

 暴力解法时间复杂度高,

2.双指针法

题目中有一个条件数组是有序的,数组平方之后,最大值不是最左边就是在最右边,逐步向中间逼近。可以利用双指针法,i指向起始位置,j指向终止位置,比较nums[i]**2与nums[j]**2的大小,取较大者。

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        size=len(nums)
        result=[0]*size #用于存放排序后的结果
        #初始化指针位置,在数组的一头一尾
        i=0 
        j=size-1
        k=size-1 #逆序写入
        while i <= j: #注意是i<=j
            if nums[i]**2 > nums[j]**2:
               result[k] = nums[i]**2
               i += 1 #左边指针往前移一位
               k -= 1
            else:
                result[k] = nums[j]**2
                j -= 1 #右边指针往后移一位
                k -= 1
        return result

注意while循环中,循环条件是i<=j,不是i

明确指针各自代表的含义

209.长度最小的子数组

题目链接:. - 力扣(LeetCode)

文章讲解:代码随想录

视频讲解:拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili

解题方法:滑动窗口                                                                                                                        我觉得滑动窗口跟双指针差不多,本质上都需要两个指针指向数组元素。                                       

注意点:滑动窗口只用一个for循环,这个循环的索引,一定是表示滑动窗口的终止位置。

这道题中,如果当前窗口的值大于target了,窗口就要向前移动了,即起始位置向前移动。窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        sumn = 0 #窗口的和
        n=float(inf) #float(inf)表示为正无穷、float(-inf)表示为负无穷
        j=0 #起始位置
        for i in range(len(nums)): #i表示终止位置
            sumn += nums[i]
            while sumn >= target:  #一定要用while循环
                n = min(n,i-j+1) 
                sumn -= nums[j]
                j=j+1
        return n if n != float(inf) else 0

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

59.螺旋矩阵II

坚持 循环不变量原则

模拟顺时针画矩阵的过程:  填充上行从左到右                                                                                                                               填充右列从上到下                                                                                                                               填充下行从右到左                                                                                                                               填充左列从下到上

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        nums = [[0] * n for _ in range(n)]
        startx, starty = 0, 0               # 起始点
        loop, mid = n // 2, n // 2          # 迭代次数、n为奇数时,矩阵的中心点
        count = 1                           # 计数

        for offset in range(1, loop + 1) :      # 每循环一层偏移量加1,偏移量从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 :			# n为奇数时,填充中心点
            nums[mid][mid] = count 
        return nums

(直接把代码随想录的代码复制过来了,自己写出来还是不对,还要再修改一下)

你可能感兴趣的:(算法)