【刷题笔记】977有序数组的平方、209长度最小的子数组、59螺旋矩阵II、54螺旋矩阵

977有序数组的平方

题目链接:
https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解:
https://www.bilibili.com/video/BV1QB4y1D7ep

思路

  • 虽然数组是非递减的,但是要考虑到数组的左半部分是负数的情况,比如数组是[-100,-50,0,10],非递减,但是平方之后,为[10000,2500,0,100],显然不是非递减的。因此我们不能从第一个数遍历到最后一个数,依次求平方,这种方法只适用于数组中的数字全部大于0的情况。
  • 假设数组是从负数过渡到正数,那么求平方后,最大的数应该出现在最左边或最右边。对于全为正数或全为负数的情况,可以看作它的一种特殊形式。
  • 因此我们选择用左右指针从两头向中间进行收缩,依次比对平方后的数值,满足要求就加入结果集。
  • 注意这里while中为什么是<=号,而不是<号?考虑一种极端情况,即全为负数的情况,当处理完倒数第二个数,left向后移动,此时left和right都指向了最后一个数,即left=right。如果此时退出循环,那么就会漏掉最后一个数。所以while中的条件是left<=right。
class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        ans = []
        n = len(nums)
        if n == 0:
            return nums

        left = 0
        right = n-1
        while(left <= right):
            left_num = nums[left] * nums[left]
            right_num = nums[right] * nums[right]
            if left_num >= right_num:
                ans.append(left_num)
                left += 1
            else:
                ans.append(right_num)
                right -= 1
        return ans[::-1]

209长度最小的子数组

题目链接:
https://leetcode.cn/problems/minimum-size-subarray-sum/
文章讲解:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html
视频讲解:
https://www.bilibili.com/video/BV1tZ4y1q7XE

思路

  • 因为题目说了是正整数的数组和正整数的target,那么当使用两个指针作为窗口的起始和结束时,右指针向前走,一定会使窗口中的元素和变大,左指针向前走,一定会使窗口中的元素和变小。
  • 因此,我们从位置0开始,每次让右指针向前走一位,如果窗口中的元素和小于target,那么右指针继续向前走。
  • 如果窗口中的元素和大于等于target,那么此时记录窗口的长度,然后左指针向前走,收缩窗口,记录窗口长度,收缩窗口......直到窗口中的元素和小于target。那么最终我们会得到一个全局最短的窗口长度。
  • 题目要求,如果没有满足要求的窗口,那么返回0。所以这里我对最小长度的初始化就是0,因为我们遍历中计算出的窗口长度最小也是1,即窗口中只有一个数。所以,如果我们能找到符合要求的窗口,窗口长度一定是大于等于1的。所以这里初始化为0没有问题。
class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        left = 0
        ans = 0 # 用于记录滑动窗口中的和
        minLen = 0 # 用于记录最小长度

        for right in range(0, n):
            ans += nums[right] # right向前走,更新窗口的和

            if ans < target: # 如果窗口的和小于target,那么right继续向前走
                continue

            # 如果窗口和大于target,此时left持续向前走,收缩窗口,并更新窗口长度
            while(ans >= target): 
                # right-left+1是窗口的长度
                minLen = min(right-left+1, minLen) if minLen != 0 else right-left+1
                # 窗口收缩
                ans -= nums[left] 
                left += 1 
        return minLen

59螺旋矩阵II

题目链接:
https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:
https://www.bilibili.com/video/BV1SL4y1N7mV/

思路

  • 这里用的是螺旋矩阵的通用写法,注意填充的时候要有原则,以最外面一圈为例,填充第一行时,不填充最后一列的元素;填充最右列的时候,不填充最后一行的元素。四个方向都按照这个原则,就不会写乱。
  • while的条件为什么是top<bottom和left<right,而不是top<=bottom和left<=right?
  • 若n为偶数,以2x2的矩阵为例,四个方向打印一圈后,top=1,right=0,bottom=0,left=1,所以不管使用<还是<=,都会退出循环,是没有影响的。
  • 重点在于n为奇数的情况,以3x3的矩阵为例,四个方向打印一圈后,top=1,right=1,bottom=1,left=1,即,若n为奇数,剩中间一个空的时候,四个指针的数值一定是相同的,即在最中心的位置相遇。如果使用<号,此时不会继续循环,那么我们直接对最后一个空位置赋值即可;如果使用<=号,那么此时仍旧会进入循环,我们前面说过,比如填充第一行时,我们其实只对[left,right-1]的位置进行了填充,即[left,right)的左闭右开区间。那么当四个指针相遇时,左闭右开的区间其实已经没有意义了,就不需要再进入了。
class Solution(object):
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        if n == 0:
            return []
        maxtrix = [[0] * n for i in range(n)]

        top = 0
        right = n-1
        bottom = n-1
        left = 0
        count = 1

        while(top < bottom and left < right):
            for i in range(left, right):
                maxtrix[top][i] = count
                count += 1
            
            for j in range(top, bottom):
                maxtrix[j][right] = count
                count += 1

            for p in range(right, left, -1):
                maxtrix[bottom][p] = count
                count += 1

            for q in range(bottom, top, -1):
                maxtrix[q][left] = count
                count += 1

            # 一圈转完之后,再更新指针
            top += 1
            right -= 1
            bottom -= 1
            left += 1

        # 如果n为奇数,那么还剩中间一个位置需要填
        if n % 2 == 1:
            maxtrix[top][top] = count
        return maxtrix

54螺旋矩阵

思路

  • 这道题由于矩阵是mxn的,转圈时区间的定义稍有不同。目前也没有想到比较好的解释,后面再补充吧。
class Solution(object):
    def spiralOrder(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: List[int]
        """
        if len(matrix) == 0 or len(matrix[0]) == 0:
            return []

        m = len(matrix)
        n = len(matrix[0])
        ans = []

        top = 0
        right = n-1
        bottom = m-1
        left = 0

        while(top <= bottom and left <= right):
            for i in range(left, right+1):
                ans.append(matrix[top][i])
            top += 1
            
            for i in range(top, bottom+1):
                ans.append(matrix[i][right])
            right -= 1
            
            if top <= bottom:
                for i in range(right, left-1, -1):
                    ans.append(matrix[bottom][i])
                bottom -= 1

            if left <= right:
                for i in range(bottom, top-1, -1):
                    ans.append(matrix[i][left])
                left += 1

        return ans
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • 《无题》 酒冷了 可再温 情凉了 不再热 人生单行道 错过不重来 且行且珍重 莫负有情人
    0t88lw阅读 91评论 0 0
  • isNaN() 判断一个变量是否为非数字类型,是数字返回false,非数字返回true
    ccda99162290阅读 52评论 0 0
  • 任务清单 昨日完成的任务: 1、看书一个小时。 2、学习20分钟,学的是与工作相关的一份资料,资料预计本月学习完成...
    芽儿阅读 102评论 0 2
  • ## 一、java找不到符号 如果你的代码里没有报错,明明是存在的。但是java报错找不到符号。如下所示, ![在...
    sky_fly阅读 103评论 0 1
  • 我向大家介绍一种勤恳忠诚的动物 “牛”,牛怎么勤恳呢 ?在古代的时候 ,牛一直在田地里为农民干活 ,它忠诚于人,不...
    诗仙书童阅读 317评论 0 1