【Day2】代码随想录算法训练营 - 数组(二)

2023-05-16

Content

  • 题目一:977. 有序数组的平方
    • 题目描述
    • 解题思路
    • 代码
  • 题目二:209. 长度最小的子数组
    • 1. 题目描述
    • 2. 解题思路
    • 3. 代码
      • 3.1 暴力解法
      • 3.2 左右指针滑动窗口法
  • 题目三:59. 螺旋矩阵II
    • 题目描述
    • 解题思路
    • 代码

题目一:977. 有序数组的平方

题目描述

个人觉得题目描述有些问题“非递减顺序”不太严谨,[4, 5, 4, 7, 9, 2]也是非递减序列。猜测题目想表达“递增序列”。
在这里插入图片描述

解题思路

简单想法:双指针从左右端分别算平方数,哪个大则添加入新列表,依次遍历即可,最后返回逆序新列表。
时间复杂度:O(n)
空间复杂度:O(n)

代码

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

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

1. 题目描述

在这里插入图片描述

2. 解题思路

暴力破解法(Can’t AC,超时),原因在于对于数组过长(目测元素数量10000+),并且很多种连续元素求和能满足目标条件
这里重点归纳双指针“滑动窗口”方法。
方法:

left, right = 0
min_len = len(nums)
total_sum = 0 # 左指针和右指针之间元素求和
for right in range(0, len(nums)):
    total_sum += nums[right]
    while total_sum >= target:
        left

左指针和右指针之间元素求和记为sum(以下描述sum会根据左右指针变动自动更新值),右指针控制结束位置,左指针控制开始位置,左右指针初始化均为0.

  • sum小于目标值时,一直动右指针
  • sum大于等于目标值时,左指针右移并记录最短长度
  • 右指针右移直至数组最后一个位置

优点:

  • 最直观优点为减少了暴力解法中重复的求和操作
  • 虽然也是两层循环(for+while),其中外层for控制右指针,内层while循环控制左指针,但是每次执行循环(不论是内循环还是外循环)左右指针必有一个指针在动,这样最多左右指针同时移动到末尾(即[1, 1, 1, 1, 100], 101这种输入情况), 因此时间复杂度为O(2*n)
  • 右指针的作用即增加新元素,左指针的作用为及时剔除掉没有用的元素

3. 代码

3.1 暴力解法

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        min_len = len(nums) + 1
        for i in range(len(nums)):
            total_sum = 0
            this_len = 0
            for j in range(i, len(nums)):
                total_sum += nums[j]
                this_len += 1
                if total_sum >= target and this_len < min_len:
                    min_len = this_len
                    break
            if total_sum < target:
                if min_len == len(nums) + 1:
                    return 0
                else:
                    return min_len
        if min_len == len(nums) + 1:
            return 0
        else:
            return min_len          

3.2 左右指针滑动窗口法

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        min_len = len(nums)
        this_len = 0
        left, right = 0, 0
        total_sum = 0
        for right in range(len(nums)):
            total_sum += nums[right]
            this_len += 1
            while total_sum >= target:
                total_sum -= nums[left]
                left += 1
                this_len -= 1
                min_len = min(this_len, min_len)
        # 不符合条件时min_len == len(nums)恒成立
        if min_len == len(nums):
            return 0
        # 符合条件时min_len < len(nums)恒成立
        else:
            return min_len + 1

题目三:59. 螺旋矩阵II

题目描述

在这里插入图片描述

解题思路

开始想的太复杂了,其实很多if/else条件根本用不到(例如往右走到头根本不用考虑往上走的情况即不用考虑row_direction=-1的情况,此时row_direction=1恒成立,类似不存在情况还有很多),实际上row_directioncolumn_direction只需其中一个即可。

本题解法的关键在于弄明白if/else的判断条件:

  • 前提条件:往上下左右走的条件均为下一个位置不为空且下一个位置不到边界
  • 由顺时针决定了以下两点
    • 如果之前往右走,则走到头一定往下走
    • 如果之前往左走,走到头一定往上走
  • 往上或者下走到头则左右方向颠倒

代码

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        init_num = 0
        row = 0
        column = 0
        this_num = 1
        column_direction = 1
        result = [[init_num] * n for i in range(n)]
        while this_num != n * n:
            result[row][column] = this_num 
            this_num += 1
            if column_direction == 1:
                if column != n - 1 and result[row][column + 1] == init_num:
                    column += 1
                else:
                    if row != n - 1 and result[row + 1][column] == init_num:
                        row += 1
                    else:
                        column_direction = -1
                        column -= 1
            else:
                if column != 0 and result[row][column - 1] == init_num:
                    column -= 1
                else:
                    if row != 0 and result[row - 1][column] == init_num:
                        row -= 1
                    else:
                        column_direction = 1
                        column += 1
        result[row][column] = n * n
        return result
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Day2】代码随想录算法训练营 - 数组(二) 的相关文章

  • 搭建一站式OpenHarmony设备开发Windows开发环境

    搭建一站式OpenHarmony设备开发Windows开发环境 作者 xff1a 坚果 团队 xff1a 坚果派 公众号 xff1a 大前端之旅 润开鸿技术专家 xff0c 华为HDE xff0c InfoQ签约作者 xff0c OpenH
  • 关于OpenHarmony蜂窝通信框架能力的说明

    蜂窝通信框架能力 xff08 如需提供完整蜂窝通信能力需芯片厂商适配支持HDI接口 xff09 xff1a 支持双卡管理 xff0c 双卡通话 短信 搜网等基础能力接口和框架 支持VoLTE语音通话接口和框架 xff08 需要芯片厂商实现I
  • 第三方登录用户信息表设计

    user表 xff1a 站内账号表 xff0c 即原始的账号 密码信息表 字段有 user id username password social account表 xff1a 第三方账号信息表 如 wx account 微信账号信息表 a
  • HarmonyOS Codelabs最新参考

    HarmonyOS Codelabs最新参考 作者 坚果 团队 坚果派 公众号 大前端之旅 润开鸿技术专家 华为HDE InfoQ签约作者 OpenHarmony布道师 擅长HarmonyOS应用开发 熟悉服务卡片开发 在 战码先锋 活动中
  • OpenHarmony Stage模型下的窗口开发

    Stage模型下的窗口开发 作者 坚果 团队 坚果派 公众号 大前端之旅 润开鸿技术专家 华为 HDE InfoQ 签约作者 OpenHarmony 布道师 擅长 HarmonyOS 应用开发 熟悉服务卡片开发 在 战码先锋 活动中作为大队
  • 大教堂与集市

    文章目录 第一章 教堂与市集第二章 信一定要寄到第三章 拥有用户的重要第四章 尽早发布 xff0c 经常发布新版本第五章 有多少眼球驯服了复杂度第六章 今花非昨花 xff1f 第七章 Popclient 变成 Fetchmail第八章 Fe
  • 大聪明教你学Java | Spring Boot 项目设置 X-Content-Type-Options 响应头

    前言 我们在开发应用系统的时候 xff0c 总会遇到各种各样的漏洞 xff0c 即便是项目上线后 xff0c 甲方霸霸也会找专门搞安全的公司来对我们的应用系统进行扫描 xff0c 扫描完后或多或少也会出现一些漏洞 xff0c 我们就得加班对

随机推荐