leetcode 力扣刷题 旋转矩阵(循环过程边界控制)

力扣刷题 旋转矩阵

  • 二维矩阵按圈遍历(顺时针 or 逆时针)遍历
  • 59. 旋转矩阵Ⅱ
  • 54. 旋转矩阵
  • 剑指 Offer 29. 顺时针打印矩阵

二维矩阵按圈遍历(顺时针 or 逆时针)遍历

下面的题目的主要考察点都是,二维数组从左上角开始顺时针(或者逆时针)按圈遍历数组的过程。顺时针按圈遍历的过程如下:
在这里插入图片描述

对于每一圈,分为四条边,循环遍历就好。这时,对于四个角的元素的处理,可以将四条边的遍历分为以下两种情况:
在这里插入图片描述

  • 第一种:每条边都从对应一角开始,遍历对应边的时候,最后一个元素留给下一条边;比如第一条绿色的边,最后一个元素就没有访问;第二条黄色的边就从左上角元素开始,相应的最左下角的元素没有访问;以此类推;
    代码实现(C++):
        //count表示访问了的元素个数,控制遍历完数组没有while(count <= n*n){//i,j是行、列的下标,每次总是从[0,0],[1,1]开始一圈循环int i = p;int j = p;//每圈最上面一条边的遍历         while(j < n - 1 - p){//因为最一个元素[i][n-1-p]留给下一条边,因此这里不取等ans[i][j++] = count++;}//每圈最右边的一条边的遍历while(i < n - 1 - p){//因为最一个元素[n-1-p][j]留给下一条边,因此这里不取等ans[i++][j] = count++;}//每圈最下面一条边的遍历while(j > p){//因为最后一个元素[i][p]留给下一条边,因此这里不取等ans[i][j--] = count++;}//每圈最左边的一条边的遍历while(i > p){//因为[p][p]就是这一圈的起始点,在第一条边就遍历过了,所以这里取等ans[i--][j] = count++;}p++;}
  • 第二种:遍历每一条边时,就将该边所有未被访问的元素全部遍历;比如第一条绿色的,最后一个元素就访问了;然后第二条边黄色的就对应列的第二个开始,因为第一个已经被访问了;之后的边以此类推;
    代码实现(C++):
        //count控制遍历完了没有while(count <= n*n){   //遍历最上边的一条边        for(int i = left; i <= right ; i++){ans[top][i] = count++;}//遍历完后top++top++;//遍历最右边的边for(int i = top; i <= bottom; i++){ans[i][right] = count++;}//遍历完后right--right--;//遍历最下边的边for(int i = right; i >= left ;i--){ans[bottom][i] = count++;}//遍历完后bottom--bottom--;//遍历最左边一条边for(int i = bottom; i >= top; i--){ans[i][left] = count++;}//遍历完后left++left++;}

59. 旋转矩阵Ⅱ

螺旋矩阵 II
题目内容如下:
在这里插入图片描述
注意点是n*n的正方形矩阵,行列数量相同。只要按照前面提到的顺时针访问数组的过程中,给每个位置递增赋值就好。按圈遍历的过程中,需要循环遍历多少次呢?答案是(n+1)/2次。
在这里插入图片描述
但是按照上面提到的第一种俺圈遍历的过程中:

  • n为偶数时,每次减少2行,2 列,最后刚好遍历完;
  • n为奇数时,最后一次只有单独一个,因为每条边的最后一个元素都留给下一条边了,所以实际上没有哪条边去遍历了。比如n=5,p=2时,i=2,j=2,n-1-p=2,由于i=j=p=n-1-p,第一种代码提到的四种循环条件都不满足。所以在最后要单独给这个位置赋值。代码如下(C++):
class Solution {
public:vector<vector<int>> generateMatrix(int n) {int count = 1;int i, j, p;vector<vector<int>> ans(n,vector<int>(n));//因为n为奇数的最后一圈在最后单独赋值,所以这里p<n/2就好for(int p = 0; p < n/2; p++){i = p;j = p;         while(j < n - 1 - p){ans[i][j++] = count++;}while(i < n - 1 - p){ans[i++][j] = count++;}while(j > p){ans[i][j--] = count++;}while(i > p){ans[i--][j] = count++;}}//n为奇数时,最后一个位置(最中间)单独赋值if( n%2 != 0){ans[n/2][n/2] = count;}return ans;}
}; 

对于第二种按圈遍历的过程,因为用top//bottom//left//right来控制,最后中间位置的能够遍历到,不需要额外的处理,代码如下(C++):

class Solution {
public:vector<vector<int>> generateMatrix(int n) {        vector<vector<int>> ans(n,vector<int>(n));int left = 0, right = n - 1;int top = 0, bottom = n -1;int count = 1;while(count <= n*n){int i;for(i = left; i <= right ; i++){ans[top][i] = count++;}top++;for(i = top; i <= bottom; i++){ans[i][right] = count++;}right--;for(i = right; i >= left ;i--){ans[bottom][i] = count++;}bottom--;for(i = bottom; i >= top; i--){ans[i][left] = count++;}left++;}return ans;}
}; 

54. 旋转矩阵

54. 旋转矩阵
题意如下:在这里插入图片描述
跟上一题不同的点在于,矩阵由nn变成了==mn==,m和n不一定相等,即现在的矩阵可能不再是正方形的了。那么根据m(行数)///n(偶数)是奇数还是偶数?大小关系可以分为以下七种情况:
在这里插入图片描述
分析这7种情况,得出结论,只要满足如下两种情况之一,最后就有需要单独处理的:

  • m<n并且m是奇数(不管n是奇是偶),最终会多出来一行(因为m行数更小,行先结束圈的遍历,但是列还有更多的,所以多出来一行);
  • n<m并且n是奇数(不管m是奇是偶),最终会多出来一列(因为n列数更小,列先结束圈的遍历,但是行还有很多,所以多出来一列);
    (m=n同为奇数的情况可以归为上述任意一种)。
    代码实现的过程,就是最终会判断一下是否出现上面的情况,然后单独处理这一行///这一列就好,代码如下:
class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {int step_i = 0, step_j = 0, index = 0;int m = matrix.size(), n = matrix[0].size();vector<int> ans(m*n);//与上一题代码基本一致,只是<m/2和<n/2需要单独判断while(step_i < m/2 && step_j < n/2){int i = step_i;int j = step_j;for(; j < n - 1 -step_j; j++){ans[index++] = matrix[i][j];}for(; i < m - 1 - step_i; i++){ans[index++] = matrix[i][j];}for(; j > step_j; j--){ans[index++] = matrix[i][j];}for(; i > step_i ;i--){ans[index++] = matrix[i][j];}step_i++;step_j++;}//行是奇数并且m<n,剩下一行if(m%2 != 0 && step_i == m/2){for(int j = step_j; j < n - step_j; j++)ans[index++] = matrix[step_i][j];}//列是奇数并且n<m,剩下一列else if(n%2 != 0 && step_j == n/2){for(int i = step_i; i < m -step_i; i++ )ans[index++] = matrix[i][step_j];} return ans;    }
};

如果用第二种按圈遍历的方法,更简单,只是在大循环内依次进行的四个小循环,需要在最后两个循环添加额外的循环条件

class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {int m = matrix.size(), n = matrix[0].size();vector<int> ans(m*n);int left = 0, right = n - 1;int top = 0, bottom = m - 1;int index = 0;while(index < m*n){for(int i = left; i <= right; i++){ans[index++] = matrix[top][i];}top++;for(int i = top; i <= bottom; i++){ans[index++] = matrix[i][right];}right--;//需要添加额外的条件 index < m*n (根据实际题目要求选择对应的约束条件for(int i = right; i >=left && index < m*n; i--){ans[index++] = matrix[bottom][i];}bottom--;//需要添加额外的条件index < m*n (根据实际题目要求选择对应的约束条件for(int i = bottom; i >= top && index < m*n; i--){ans[index++] = matrix[i][left];}left++;}return ans;}
};

为什么要添加这两个?请看下例:
在这里插入图片描述

如果不在内层的四个循环的后两个中添加额外的限制,就会出现多遍历的情况。

剑指 Offer 29. 顺时针打印矩阵

剑指 Offer 29. 顺时针打印矩阵
和54是一样的题目,只是注意m和n可能等于0。

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

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

相关文章

输出无重复的3位数和计算无人机飞行坐标

编程题总结 题目一&#xff1a;输出无重复的3位数 题目描述 从{1,2,3,4,5,6,7,8,9}中随机挑选不重复的5个数字作为输入数组‘selectedDigits’&#xff0c;能组成多少个互不相同且无重复数字的3位数?请编写程》序&#xff0c;从小到大顺序&#xff0c;以数组形式输出这些3位…

C# Linq源码分析之Take (一)

概要 在.Net 6 中引入的Take的另一个重载方法&#xff0c;一个基于Range的重载方法。因为该方法中涉及了很多新的概念&#xff0c;所以在分析源码之前&#xff0c;先将这些概念搞清楚。 Take方法基本介绍 public static System.Collections.Generic.IEnumerable Take (this …

【LeetCode: 2811. 判断是否能拆分数组】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

NavMeshPlus 2D寻路插件

插件地址:h8man/NavMeshPlus&#xff1a; Unity NavMesh 2D Pathfinding (github.com) 我对Unity官方是深恶痛觉,一个2D寻路至今都没想解决,这破引擎早点倒闭算了. 这插件是githun的开源项目,我本身是有写jps寻路的,但是无法解决多个单位互相阻挡的问题(可以解决但是有性能问…

vue3+ts使用antv/x6 + 自定义节点

使用 2.x 版本 x6.antv 新官网: 安装 npm install antv/x6 //"antv/x6": "^2.1.6",项目结构 1、初始化画布 index.vue <template><div id"container"></div> </template><script setup langts> import { onM…

Python爬虫——scrapy_基本使用

安装scrapy pip install scrapy创建scrapy项目&#xff0c;需要在终端里创建 注意&#xff1a;项目的名字开头不能是数字&#xff0c;也不能包含中文 scrapy startproject 项目名称 示例&#xff1a; scrapy startproject scra_baidu_36创建好后的文件 3. 创建爬虫文件&…

MySQL表的操作

文章目录 MySQL表的操作1. 创建表2. 查看表2.1 查看数据库中存在的表2.2 查看表的属性2.3 查看创建时表的详细信息 3. 修改表3.1 向表中添加记录3.2 添加列3.3 修改列的数据类型3.4 删除列3.5 表的重命名3.6 修改列名 4. 删除表 MySQL表的操作 1. 创建表 CREATE TABLE table_…

博客系统【架构】

用户管理 实现用户的注册、登录、注销等功能 使用Redis做缓存处理、阿里云短信服务 确保用户身份验证和安全性 使用Jwt来鉴权 userId (主键&#xff0c;自增长) username (唯一&#xff0c;用户名)【用于普通登录】email (唯一&#xff0c;用户的电子邮件地址) password (存储…

zabbix监控tomcat

一、zabbix监控Tomcat1.1 zbx-agent配置1.1.1 关闭防火墙&#xff0c;将安装 Tomcat 所需软件包传到/opt目录下1.1.2 安装JDK1.1.3 设置JDK环境变量1.1.4 安装启动Tomcat1.1.5 配置 JMX 1.2 zbx-server配置1.2.1 安装zabbix&#xff08;省略&#xff0c;可看上一篇博客&#xf…

Docker自动化部署安装(十)之安装SonarQube

这里选择的是&#xff1a; sonarqube:9.1.0-community (推荐使用) postgres:9.6.23 数据库(sonarqube7.9及以后便不再支持mysql&#xff0c;版本太低的话里面的一些插件会下载不成功的) 1、docker-sonarqube.yml文件 version: 3 services:sonarqube:container_name: sonar…

Redis详解

Redis 简介 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的高性能键值对存储数据库&#xff0c;最初由 Salvatore Sanfilippo 开发&#xff0c;它在内存中存储数据&#xff0c;并提供了持久化功能&#xff0c;可以将数据保存到磁盘中&#xff0c;是一种N…

♥ vue中$forceUpdate()

♥ vue中$forceUpdate() 1、认识 强制该组件重新渲染 鉴于 Vue 的全自动响应性系统&#xff0c;这个功能应该很少会被用到 $forceUpdate()迫使vue实例重新&#xff08;rander&#xff09;渲染虚拟DOM&#xff0c;注意并不是重新加载组件。 结合vue的生命周期&#xff0c;调用…

【论文阅读】DEPCOMM:用于攻击调查的系统审核日志的图摘要(SP-2022)

Xu Z, Fang P, Liu C, et al. Depcomm: Graph summarization on system audit logs for attack investigation[C]//2022 IEEE Symposium on Security and Privacy (SP). IEEE, 2022: 540-557. 1 摘要 ​ 提出了 DEPCOMM&#xff0c;这是一种图摘要方法&#xff0c;通过将大图划…

简单易懂的python生成器

目录 定义使用 for 循环来迭代生成器对象斐波那契 定义 在 Python 中&#xff0c;使用了 yield 的函数被称为生成器&#xff08;generator&#xff09;。Python 中的生成器&#xff08;Generator&#xff09;是一种特殊的迭代器&#xff0c;可以通过函数来创建。与常规函数不同…

Feign忽略Https的SSL最佳方案(且保证负载均衡将失效)

同时解决Https的SSL证书验证问题和feign不支持Patch请求方法的问题 代码 1. 工具类 OkHttpUtils.java import javax.net.ssl.*; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import j…

从0开始搭建ns3环境以及NetAnim简单使用

一、环境准备 ns3是基于GNU/Linux平台使用C开发的工具软件&#xff0c;在windows系统中安装使用ns3环境&#xff0c;可以使用虚拟机VMware并安装ubuntu系统来实现&#xff0c;现将本教程所用到的虚拟机和系统镜像放到网盘提供下载 名称链接提取码VMware Workstation 17 Proht…

简约时尚的健康手表,智能守护每一刻,dido Y60上手

智能手表是现在很流行的一种智能设备&#xff0c;很多品牌都推出了各种各样的产品&#xff0c;但是大部分都更侧重功能和运动的方面&#xff0c;健康监测往往只是配角&#xff0c;而随着人们对自己的健康越来越重视&#xff0c;有些朋友只是单纯的需要一块专业的健康监测手表。…

选择任务管理软件:哪个更适合你的需求?

随着互联网的发展&#xff0c;知识管理是可以成为企业获得更大发展前景的神兵利器&#xff0c;任务协同&#xff0c;是服务于中小型团队&#xff0c;或者大型机构的终端组织。来看看这款国外流行的任务管理软件Zoho Projects。 任务管理是企业协同的重要组成部分。 任务管理是企…

Bitcoin 加速交易操作示例

这里以 Bitcoin Ordinals NFT 为例&#xff0c; 进行加速交易演示 第1步&#xff1a;新建子账户 温馨提示&#xff1a;如果有多条鱼未确认&#xff0c;也只需1个账户即可&#xff0c;不必搞多个子账户 第2步&#xff1a;切换回到老地址&#xff08;Account 1&#xff09; 第3步…

【Kubernetes】Kubernetes的PV和PVC的用法

PV、PVC 前言一、 存储卷1. emptyDir 存储卷1.1 概念1.2 实例 2. hostPath 存储卷2.1 概念2.2 实例 3. nfs共享存储卷 二、PV 和 PVC1. 概念1.1 PV1.2 PVC1.3 PVC 的使用逻辑1.4 创建机制1.5 PV 和 PVC 的生命力周期1.6 创建及销毁 PV 的流程 2. PV 和 PVC 的创建2.1 查看定义2…