首页 > 其他分享 >螺旋矩阵练习

螺旋矩阵练习

时间:2024-06-01 21:57:57浏览次数:19  
标签:startX matrix 螺旋 int 练习 矩阵 mid ++

59. 螺旋矩阵 II

题目介绍:

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例 1:
在这里插入图片描述

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例 2:

输入:n = 1
输出:[[1]]

提示:
1 <= n <= 20

思路:

本题主要就是模拟螺旋矩阵的过程,让每条边都遵循同一个规律,如都左开右闭,即留下每行或每列的最后一个元素作为下一条边的起始元素。以及每圈循环时起始坐标、边长需要改变。另外还需注意假如n为单数时,会留下最后一个中心点需要另外填充。
具体代码如下:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {

        vector<vector<int>> res( n , vector<int>(n,0) ) ;       //建立矩阵
        int startX = 0 , startY = 0 ;    //每圈的起始坐标,比如第一圈为(0,0)
        int loop = n/2  ;  //需要循环的圈数
        int mid = n/2 ;     //如果n为单数的话,会剩下最后一个中心点,坐标即(mid ,mid)
        int offset = 1 ;  //用于调整每圈循环的行列长度
        int count = 1 ;  //从1开始计数,填入矩阵中

        while(loop--){
            int i = startX  ;
            int j = startY ;
            //模拟上行,从左至右填充,左闭右开
            for( j ; j < n - offset ; j++ ){
                res[i][j] = count++ ; 
            }
            //模拟右列,从上至下,左闭右开
            for( i ; i < n-offset ; i++){
                res[i][j] = count++ ; 
            }
            //模拟下行,从右至左,左闭右开
            for( j ; j > startY ; j--){
                res[i][j] = count++ ; 
            } 
            //模拟左列,从下至上,左闭右开
            for( i ; i > startX ;i-- ){
                res[i][j] = count++ ; 
            }
            //每一轮循环,起始坐标加1 ,行列长度减1 
            startX++ ;
            startY++ ; 
            offset++ ;
        }

        //如果n为单数,则填充最后的中心点
        if( n%2 != 0 )  res[mid][mid] = count ; 

        return res ; 
    }
};

54. 螺旋矩阵

题目介绍:

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:
在这里插入图片描述

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:
在这里插入图片描述

输入: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]

提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100

思路:

与上题不同,本题是给出了一个矩阵,需要我们按照顺时针循环输出这个矩阵且并不是等边矩阵。所以我们首先需要判断循环条件:获取矩阵的长和宽:matrix.size() 、matrix[0].size() ,再根据更小的那个数判断循环几圈,即min(matrix.size() , matrix[0].size() )/2。
每圈遵循的统一规律:左开右闭。
每圈循环时的变量:起始坐标、行的长度以及列的长度。
当行列数较小的那个为单数时,会剩下一些元素未遍历。
具体代码如下:

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        int startX = 0 ,startY =0 ;         //每一轮起始的坐标
        int m = matrix.size()  ;        //矩阵的行数
        int n = matrix[0].size() ;      //矩阵的列数
        int loop , mid ;        
        if( m < n ){
            //当行数小于列数时,根据行数来判断循环几圈
            loop = m/2 ; 
            mid = m/2  ;
        }else{
            //当列数大于行数时,根据列数判断循环几圈
            loop = n/2 ; 
            mid = n/2  ;
        }
        
        int offset = 1 ;    //以此判断每轮循环时,行列的长度
        
        vector<int> result ; 

        if(matrix.size() == 0 || matrix[0].size() == 0 )    return {} ;    //当矩阵为空时,返回空集合

        while( loop-- )
        {
            int i = startX ;
            int j = startY ; 

            //遍历上行,从左至右,左开右闭
            for( j ; j < n - offset ; j++){
                result.push_back( matrix[i][j] ) ;
            }
            //遍历右列,从上至下,左开右闭
            for( i ; i < m - offset ; i++ ){
                result.push_back( (matrix[i])[j] );
            }
            //遍历下行,从右至左,左开右闭
            for( j ; j > startY ; j--){
                result.push_back( matrix[i][j] ) ;
            }
            //遍历左列 ,从下至上,左开右闭
            for( i ; i > startX ; i-- )
            {
                result.push_back( matrix[i][j] ) ; 
            }

            startX++ ;
            startY++ ;
            offset++ ; 
        }
        //当行数或者列数为单的时候,最后一定会剩下一行或者一列数据未遍历
        if( min(m,n)%2 != 0){
            if(m < n){
                //当行数小于列数时,剩下一行未遍历
                for( int i = 0 ; i < n - 2*mid  ; i++ ){
                 result.push_back( matrix[mid][mid+i] ) ;
                }
            }else{
                //当行数大于等于列数的时候,剩下一列未遍历
                for( int i = 0 ; i < m - 2*mid  ; i++ ){
                 result.push_back( matrix[mid+i][mid] ) ;
                }
            }
            
        }

        return result ; 
    }
};

标签:startX,matrix,螺旋,int,练习,矩阵,mid,++
From: https://blog.csdn.net/weixin_45101231/article/details/139298101

相关文章

  • 动手学深度学习4.6 暂退法-笔记&练习(PyTorch)
    以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。本节课程地址:丢弃法_哔哩哔哩_bilibili本节教材地址:4.6.暂退法(Dropout)—动手学深度学习2.0.0documentation(d2l.ai)本节开源代码:...>d2l-zh>pytorch>chapter......
  • C++Primer Plus第十一章类的使用,课后练习2,还是醉汉回家的故事 3,最慢和最快及平均概率
    修改程序清单11.15,使之报告N次测试中的最高、最低和平均步数(其中N是用户输入的整数)而不是报告每次测试的结果。头文件和实现文件不变,这里为大家方便还是贴上代码//vect.h--Vectorclasswith<<,modestate#if1#ifndef VECTOR_H_ #defineVECTOR_H_#include<io......
  • C++Primer Plus第十一章类的使用,课后练习1,还是醉汉回家的故事
    编程练习11.91.修改程序清单11.5,使之将一系列连续的随机漫步者位置写入到文件中。对于每个位置,用步号进行标示。另外,让该程序将初始条件(目标距离和步长)以及结果小结写入到该文件中。该文件的内容与下面类似:TargetDistance:100,stepSize:200:(xy)=(0,0)1:(x,y)=(-11.4......
  • matlab练习程序(LQR路径跟踪)
    LQR是一种优化控制方法,设计目标是找到一组控制输入,使得线性系统的状态轨迹尽可能地接近目标,同时使控制输入尽可能小。其目标函数是一个二次型成本函数。分为以下几个步骤:1.设系统动态方程为:其中x为状态量,u为控制输入,A和B为状态转移和控制矩阵。2.定义一个性能指标,即控制器......
  • 从矩阵角度理解吉司机线段树
    前几天打算学写吉司机线段树,写到区间历史最值的时候炸了,这些标记的复杂性让我有点望而却步,但是当我看到warzone大佬的矩阵角度理解吉司机线段树时,我知道这就是我想看的东西。作为我学完之后的总结,我决定写一篇学习笔记。warzone的题解更为简洁,而我写的这篇会稍微更加详细一点......
  • C语言练习题之——从简单到烧脑(12)(每日两道)
    题目1:找出1到99之间的全部同构数, 同构数:它出现在平方数的右边,例如:5是25右边的数,25是625右边的数,5和25都是同构数。#include<stdio.h>intmain(){ intsum=0,left=0,right=0; printf("1-99之间的同构数:\n"); for(inti=1;i<100;i++) { inta=i*i;......
  • C语言练习题之——从简单到烧脑(10)(每日两道)
    题目1:二位数组的应用:输入一个3X5的整数矩阵,输出其中的最大值,最小值,和他们的下标#include<stdio.h>intmain(){ inta[3][5],max,min,maxi,maxj,mini,minj; //最大值最小值,和下标分别定义变量存储 inti,j; for(i=0;i<3;i++) for(j=0;j<5;j++)......
  • Java练习(综合运用继承性、多态性、接口)
    在这个练习中,我们定义了一个接口`Animal`,其中包含一个方法`sound()`。之后,我们创建了一个基类`Mammal`,实现了`Animal`接口,并提供了一个默认的`sound()`方法实现。接着,我们定义了两个继承自`Mammal`的子类`Dog`和`Cat`,分别重写了`sound()`方法。在`main`方法中,我们创建了一个......
  • 字典课后练习题 多加练习呀!
    info_dict={"王":{"部门":"科技部","工资":3000,"级别":1},"周":{"部门":"市场部","工资":5000,......
  • 统计子矩阵+二维前缀和+滑动窗口
    题目链接:0统计子矩阵-蓝桥云课(lanqiao.cn)代码#include<iostream>usingnamespacestd;constintN=505;intnum[N][N];intmain(){ intn,m,k; cin>>n>>m>>k; intcount=0; for(inti=1;i<=n;i++){ for(intj=1;j......