力扣刷题-数组-螺旋矩阵

模拟过程,但却十分考察对代码的掌控能力。
重点:循环不变量原则!
第一条原则:
模拟顺时针画矩阵的过程:

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

由外向内一圈一圈这么画下去。
第二条原则:
左闭右开原则!
这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。
image.png
这里每一种颜色,代表一条边,我们遍历的长度,可以看出每一个拐角处的处理规则,拐角处让给新的一条边来继续画。这也是坚持了每条边左闭右开的原则。

59.螺旋矩阵II

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
image.png
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

class Solution(object):def generateMatrix(self, n):""":type n: int:rtype: List[List[int]]"""# 螺旋矩阵 重点考察代码能力 不涉及算法# 遇到判断循环边界的题目 要遵循 循环不变量 1. 上下行 左右列的遍历原则 2. 左闭右开原则result = [[0]*n for _ in range(n)]startx ,starty = 0, 0 # 起始位置 因为一般是循环里面用i j loop = n // 2 # 循环个数 需要转几个圈mid = n // 2 # 若n为奇数 需要单独处理中间的一个数 result[mid][mid]offset = 1 # 第一圈offset当然为1 下一圈需要再加1 offset目的就是保持左闭右开原则count = 1 # 计数 就是每个位置填充的数# 开始循环while loop > 0:i = startx # 对于不同循环 每次起始的x y 不一样j = starty# 上行 左闭右开for j in range(starty, n-offset):result[startx][j] = countcount += 1j += 1# 右列for i in range(startx, n-offset):result[i][j] = countcount += 1i += 1# 下行while j > starty:result[i][j] = countcount += 1j -= 1# 左列while i > startx:result[i][j] = countcount += 1i -= 1loop -= 1 # 循环数减1offset += 1 # offset加1startx += 1starty += 1if n %2 :result[mid][mid] = countreturn result

54.螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:(方阵)
image.png
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
image.png
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
解题:
与59.螺旋矩阵II相同的是:两者都是模拟矩形的顺时针旋转,所以核心依然是依然是坚持循环不变量,按照左闭右开的原则
与59.螺旋矩阵II不同的是:前题中的螺旋矩阵是正方形,只有正方形的边长n一个边界条件,而本题中,需要考虑长方形的长和宽(m行和n列)两个边界条件。自然,m可以等于n,即前题可视为本题在m==n的特殊情况。
我们从最一般的情况开始考虑,与59.螺旋矩阵II题解对比起来,m和n的带入,主要引来两方面的差异:

  • **loop的计算: **本题的loop计算与59.螺旋矩阵II算法略微差异,因为存在rows和columns两个维度,可自行分析,loop只能取min(rows, columns),例如rows = 5, columns = 7,那loop = 5 / 7 = 2
  • mid的计算及填充: 1、同样的原理,本题的mid计算也存在上述差异; 2、 如果min(rows, columns)为偶数,则不需要在最后单独考虑矩阵最中间位置的赋值 如果min(rows, columns)为奇数,则矩阵最中间位置不只是[mid][mid],而是会留下来一个特殊的中间行或者中间列,具体是中间行还是中间列,要看rows和columns的大小,如果rows > columns,则是中间列,相反,则是中间行

可以自己举例画图分析。

class Solution(object):def spiralOrder(self, matrix):""":type matrix: List[List[int]]:rtype: List[int]"""m = len(matrix) # 行数n = len(matrix[0]) # 列数result = []if m == n: # 当矩阵为方阵时startx, starty = 0, 0offset = 1loop = n // 2mid = n // 2while loop:i = startxj = starty# 上行for j in range(starty, n-offset):result.append(matrix[startx][j])j += 1# 右列for i in range(startx, n-offset):result.append(matrix[i][j])i += 1# 下行while j > starty:result.append(matrix[i][j])j -= 1# 左列while i > startx:result.append(matrix[i][j])loop -= 1offset += 1startx += 1starty += 1if n % 2:result.append(matrix[mid][mid])# m与n不等 则loop循环数量为 min(m,n) // 2 并且如果min(m,n)为奇数 则不再是中间位置 而可能是留下一行或者一列if m != n:startx, starty = 0, 0offset = 1loop = min(m ,n ) // 2mid = min(m, n) // 2while loop:i = startxj = startyfor j in range(starty, starty+n-offset): # 注意是startx+n-offsetresult.append(matrix[startx][j])j += 1for i in range(startx, startx+m-offset):result.append(matrix[i][j])i += 1while j > starty:result.append(matrix[i][j])j -= 1while i > startx:result.append(matrix[i][j])i -= 1loop -= 1offset += 2 # 注意这里要加2 因为外圈遍历完后,再遍历内圈,内圈的矩阵行和列相比外圈都少了两个长度startx += 1starty += 1# 处理额外的行/列数据if min(m,n)%2:if m>n: # 那就是额外的列for i in range(mid, mid+m-n+1):result.append(matrix[i][mid])else:for j in range(mid, mid+n-m+1):result.append(matrix[mid][j])return result

其实可以不用分:

class Solution(object):def spiralOrder(self, matrix):""":type matrix: List[List[int]]:rtype: List[int]"""m = len(matrix) # 行数n = len(matrix[0]) # 列数result = []# if m == n: # 当矩阵为方阵时#     startx, starty = 0, 0#     offset = 1#     loop = n // 2#     mid = n // 2#     while loop:#         i = startx#         j = starty#         # 上行#         for j in range(starty, n-offset):#             result.append(matrix[startx][j])#         j += 1#         # 右列#         for i in range(startx, n-offset):#             result.append(matrix[i][j])#         i += 1#         # 下行#         while j > starty:#             result.append(matrix[i][j])#             j -= 1#         # 左列#         while i > startx:#             result.append(matrix[i][j])#         loop -= 1#         offset += 1#         startx += 1#         starty += 1#     if n % 2:#         result.append(matrix[mid][mid])# m与n不等 则loop循环数量为 min(m,n) // 2 并且如果min(m,n)为奇数 则不再是中间位置 而可能是留下一行或者一列startx, starty = 0, 0offset = 1loop = min(m ,n ) // 2mid = min(m, n) // 2while loop:i = startxj = startyfor j in range(starty, starty+n-offset): # 注意是startx+n-offsetresult.append(matrix[startx][j])j += 1for i in range(startx, startx+m-offset):result.append(matrix[i][j])i += 1while j > starty:result.append(matrix[i][j])j -= 1while i > startx:result.append(matrix[i][j])i-=1loop -= 1offset += 2 # 注意这里要加2 因为外圈遍历完后,再遍历内圈,内圈的矩阵行和列相比外圈都少了两个长度startx += 1starty += 1# 处理额外的行/列数据if min(m,n)%2:if m>n: # 那就是额外的列for i in range(mid, mid+m-n+1):  # 注意是midresult.append(matrix[i][mid])else: # 那就是额外的行for j in range(mid, mid+n-m+1):result.append(matrix[mid][j])return result

重点在于考虑到m!=n时候如何判断循环圈数,以及什么时候要考虑循环完毕之后剩余的元素,以及如何处理。

参考:https://programmercarl.com/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/115481.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在没有第三方.NET库源码的情况,调试第三库代码?

大家好,我是沙漠尽头的狼。 本方首发于Dotnet9,介绍使用dnSpy调试第三方.NET库源码,行文目录: 安装dnSpy编写示例程序调试示例程序调试.NET库原生方法总结 1. 安装dnSpy dnSpy是一款功能强大的.NET程序反编译工具,…

ESP8266 WiFi物联网智能插座—电能计量

目录 1、芯片功能 2、性能指标 3、寄存器说明 4、UART通信协议 4.1、写操作帧格式和时序 4.2、读操作帧格式和时序 4.3、读取全电参数数据包 4.4、配置波特率 4.5、UART保护机制 5、功能说明 5.1、电流电压瞬态波形计量 5.2、有功功率 5.3、有功功率防潜动 5.4、电能计量 5.5、…

摩尔信使MThings实用功能盘点

“冗长的用户手册”与“精简的交互设计”之间势必产生一条信息鸿沟,现在就来盘点一下摩尔信使MThings有哪些隐蔽而实用的功能。 01 数据配置类 一键刷新 功能:快速读取所有位数据、寄存器数据的当前数值。 操作:双击“数值”列表头。 一键…

基于微信小程序的公司后勤服务(设备)系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明员工微信端的主要功能有:管理员的主要功能有:具体实现截图详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考论文参考源码获取 前言 💗博主介绍&#x…

【C++】搜索二叉树底层实现

目录 一,概念 二,实现分析 1. 插入 (1.)非递归版本 (2.)递归版本 2. 打印搜索二叉树 3.查找函数 (1.)非递归版本 (2.)递归版本 4. 删除函数&#x…

第一百五十一回 自定义组件综合实例:游戏摇杆二

文章目录 内容回顾实现方法位置细节示例代码我们在上一章回中介绍了如何实现 游戏摇杆相关的内容,本章回中将继续介绍这方面的知识.闲话休提,让我们一起Talk Flutter吧。 内容回顾 我们在上一章回中介绍了游戏摇杆的概念以及实现方法,并且通过示例代码演示了实现游戏摇杆的…

反编译之崩溃定位

反编译之崩溃定位 1.背景问题定位1.首先我们需要找崩溃所在的类和方法2.寻找崩溃的代码行数2.1借用反编译工具jadx查看反编译后的内容 1.背景 线上出了个崩溃(量挺大😭),但是apk是被混淆过的,一时摸不着头脑。崩溃信息如下: 主要…

Leetcode198. 打家劫舍

https://leetcode.cn/problems/house-robber/description/ 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入&…

《深度学习工业缺陷检测》专栏介绍 CSDN独家改进实战

💡💡💡深度学习工业缺陷检测 1)提供工业小缺陷检测性能提升方案,满足部署条件; 2)针对缺陷样品少等难点,引入无监督检测; 3)深度学习 C、C#部署方案&#…

AP5193 DC-DC恒流转换器 消防应急 灯汽车灯 应急日光灯太阳能灯驱动IC

AP5193是一款PWM工作模式,高效率、外围简单、 内置功率MOS管,适用于4.5-100V输入的高精度 降压LED恒流驱动芯片。电流2.5A。AP5193可实现线性调光和PWM调光,线性调光 脚有效电压范围0.55-2.6V. AP5193 工作频率可以通过RT 外部电阻编程来设定&#xff0c…

基于SpringBoot的网上超市系统的设计与实现

目录 前言 一、技术栈 二、系统功能介绍 管理员功能实现 用户功能实现 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计…

flex布局与float布局

float布局 俩栏 三栏 flex布局