【无标题】矩阵中的问题

本文通过三个LeetCode题目介绍矩阵的遍历方法,包括对角线遍历、顺时针螺旋顺序遍历和计算岛屿周长。针对每个问题,分析了其解题思路和边界处理,并给出了简单的解决方案概述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

例一:对角线遍历
链接:https://leetcode-cn.com/problems/diagonal-traverse/
题目描述:给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。

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

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

示例 2:

输入:mat = [[1,2],[3,4]]
输出:[1,2,3,4]

提示:

m == mat.length
n == mat[i].length
1 <= m, n <= 104
1 <= m * n <= 104
-105 <= mat[i][j] <= 105

题目分析:
刚看到这个题目的时候,我心里飘过的想法是就普普通通的遍历嘛,但是在真正准备写代码的时候发现并没有这么简单。
经过分析可以发现数学规律:
1、上图中红色线的对角线上的坐标之和均为偶数且在遍历时是向上移动。
2、黄色线对角线上的坐标之和均为奇数,且均为向下移动。
3、对角线上遍历时(不考虑边界)上移是(x+1,y-1),下移是(x-1,y+1)。
在弄清楚上面几条过后,这个题的思路就已经清晰了,但是我们还需要考虑边界问题,即上图中的1,4,3,8等位置。

而边界主要是第一列,最后一列和第一行,最后一行
具体边界边界判断及处理如下:

 if((x+y)%2==0){//对角线坐标之和为偶数,向上移动
                    if(y==col-1)x++;//最后一列
                   else if(x==0)y++;//第一行
                    else x--,y++;//否则就正常的斜向上移动
                }
                else{//对角线之和为奇数,向下移动
                     if(x==row-1)y++;//最后一行
                    else if(y==0)x++;//第一列
                    else x++,y--;
                }
class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& mat) {
            vector<int>result;
            int row=mat.size(),col=mat[0].size();
            if(row==0||col==0){
                return {};
            }
            int sum=row*col;
            int x=0,y=0;
            for(int i=0;i<sum;++i){
                result.push_back(mat[x][y]);
                if((x+y)%2==0){//对角线坐标之和为偶数,向上移动
                    if(y==col-1)x++;//最后一列
                   else if(x==0)y++;//第一行
                    else x--,y++;//否则就正常的斜向上移动
                }
                else{//对角线之和为奇数,向下移动
                     if(x==row-1)y++;//
                    else if(y==0)x++;
                    else x++,y--;
                }
            }
            return result;
    }
};

例二:螺旋矩阵
链接:https://leetcode-cn.com/problems/spiral-matrix/
题目描述:
给你一个 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

题目分析:
这也是一个矩阵遍历的问题,和上题相似,只要将边界条件和走一圈步数会递减的点抓住就好了。

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
            vector<int>result;
            int l=0,m=matrix.size()-1,u=0,n=matrix[0].size()-1;
            while(l<=m&&u<=n){

                for(int i=l;i<=n;i++)//向右
                result.push_back(matrix[u][i]);

                for(int i=u+1;i<=m;i++)//向下
                result.push_back(matrix[i][n]);

                for(int i=n-1;i>=l&&u<m;i--)//向左
                result.push_back(matrix[m][i]);

                for(int i=m-1;i>u&&l<n;i--)
                result.push_back(matrix[i][l]);//向上
                l++,n--,u++,m--;//n--,m--类似于“缩圈”

            }
            return result;
    }
};

例三:岛屿的周长(简单)
链接:https://leetcode-cn.com/problems/island-perimeter/
题目描述:
给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。

网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。

岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。

示例 1:
在这里插入图片描述
解释:它的周长是上面图片中的 16 个黄色的边

输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
输出:16

示例 2:

输入:grid = [[1]]
输出:4

示例 3:

输入:grid = [[1,0]]
输出:4

提示:

row == grid.length
col == grid[i].length
1 <= row, col <= 100
grid[i][j] 为 0 或 1

拿到这个题时,最容易想到的就是两种优先搜索,这确实是一种方法,但是就这个题而言,可能用优先搜索会有一些小题大做了。
我的思路是对这个矩阵遍历,在遇到与岛屿(grid[i][j]==1)的边界相连的不是岛屿时,周长加1。即只有在周围为水或者矩阵边界时,这一个小正方形的边才算作岛屿的周长。

lass Solution {
public:
    int direction[4][2]={0,1,1,0,-1,0,0,-1};
    int islandPerimeter(vector<vector<int>>& grid) {
            int result=0;
            for(int i=0;i<grid.size();i++){
                for(int j=0;j<grid[0].size();j++){
                    if(grid[i][j]==1){
                        for(int k=0;k<4;k++){
                            int x=i+direction[k][0];
                            int y=j+direction[k][1];
                            if(x<0||x>=grid.size()||y<0||y>=grid[0].size()||grid[x][y]==0){
                                result++;
                            }
                        }
                    }
                }
            }
            return result;
    }
};

代码中的direction表示四个方向。写成矩阵即:

0,1
1,0
-1,0
0,-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值