本文记录作者刷题过程中与二维矩阵相关的题目。

一、蛇形遍历矩阵

HJ35 蛇形矩阵

#include <bits/stdc++.h>
using namespace std;

int main(){
    // 获取输入
    int n;
    cin>>n;
    // 间隔变,计算各个数字
    int beg=1;// 每行的开始数字
    for(int i=1;i<=n;i++)// 每次增加的间隔越来越大
    {
        cout<<beg;
        int tmp = beg;// 每行中的数
        for(int j=i+1;j<=n;j++)// 每次增加的间隔越来越大
        {
            tmp+=j;
            cout<<" "<<tmp;              
        }
        cout<<endl;
        beg+=i;
    }
}

二、旋转矩阵

48. 旋转图像(中等难度)

class Solution {
public:
    /*
    123          147               741
    456 ->(转置) 258 -> (水平翻转)852
    789          369               963 */
    void rotate(vector<vector<int>>& matrix) {
        int m = matrix.size();//题目保证m>=1
        //int n = matrix[0].size();// 题目保证m==n
        // 转置
        for(int i=0;i<m;i++){
            for(int j=0;j<i;j++){
                swap(matrix[i][j],matrix[j][i]);
            }
        }
        // 水平翻转
        for(int i=0;i<m;i++){
            for(int j=0;j<m/2;j++){
                swap(matrix[i][j],matrix[i][m-1-j]);
            }
        }
    }
};

三、矩阵匹配字符串

79. 单词搜索(中等难度)

剑指 Offer 12. 矩阵中的路径(中等难度)

class Solution {
public:
    // 判断board[i][j]==word[k]
    bool dfs(vector<vector<char>>& board, string word,int i,int j,int k){
        if(i<0||i>=board.size()) return false;// 检查行边界
        if(j<0||j>=board[0].size()) return false;// 检查列边界
        if(board[i][j]!=word[k]) return false;// 检查当前矩阵元素==字符
        if(k==word.length()-1) return true;// 检查k是否是最后一个元素
        board[i][j]='#';// 此时和word[k]相等,设为特殊字符,代表已访问过
        // 检查当前矩阵元素的上左下右共计四个方向是否存在下一个匹配
        bool res=dfs(board, word, i, j-1, k+1)
        || dfs(board, word, i-1, j, k+1)
        || dfs(board, word, i, j+1, k+1)
        || dfs(board, word, i+1, j, k+1);
        board[i][j]=word[k];// 回溯,修复为原来的元素
        return res;
    }
    bool exist(vector<vector<char>>& board, string word) {
        // 双重循环,覆盖所有情况
        for(int i=0;i<board.size();++i){
            for(int j=0;j<board[0].size();++j){
                if(dfs(board,word,i,j,0)) return true;
            }
        }
        return false;
    }
};

四、检查矩阵元素

剑指 Offer 13. 机器人的运动范围(中等难度)

class Solution {
public:
    bool isEnter(int i,int j,int k){
        int sum=0;
        while(i){
            sum+=i%10;
            i/=10;
        }
        while(j){
            sum+=j%10;
            j/=10;
        }
        return sum<=k;
    }
    int dfs(int m,int n,int i,int j,int k,vector<vector<bool>> & visited){
        int res=0;
        if(i<0||i>=m) return res;//行超界
        if(j<0||j>=n) return res;//列超界
        if(!isEnter(i, j, k)) return res;//当前格子不可进入
        if(visited[i][j]) return res;//当前格子已经访问过
        visited[i][j]=true;//标记当前格子已访问
        res+=1;//当前格子可进入
        res+=dfs(m, n, i+1, j, k,visited);//右一格是否可进入
        res+=dfs(m, n, i, j+1, k,visited);//下一格是否可进入
        return res;

    }
    int movingCount(int m, int n, int k) {
        vector<vector<bool>> visited(m,vector(n,false));//二维bool数组
        return dfs(m,n,0,0,k,visited);
    }
};

五、查找有序矩阵

剑指 Offer 04. 二维数组中的查找

240. 搜索二维矩阵 II(中等难度)

方法一:深度优先遍历

class Solution {
public:
    bool dfs(vector<vector<int>> & matrix,int target,int i,int j){
        if(i<0||i>=matrix.size()) return false;//行超界
        if(j<0||j>=matrix[0].size()) return false;//列超界
        if(matrix[i][j]==target) return true;//当前元素就是目标值
        bool res=false;
        // 如果当前元素大,说明应该左移
        if(matrix[i][j]>target){
            res=dfs(matrix, target, i, j-1);//左一格
        }
        // 如果当前元素小,说明应该下移
        else{
            res=dfs(matrix, target,i+1, j);//下一格
        }
        return res;
    }
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.size()==0) return false;
        return dfs(matrix,target,0,matrix[0].size()-1);//从右上角遍历到左下角
    }
};

五、螺旋遍历矩阵

54. 螺旋矩阵(中等难度)

剑指 Offer 29. 顺时针打印矩阵(简单难度)

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> res; // 结果数组
        int m=matrix.size();
        if(m==0) return res;
        int n=matrix[0].size();
        // 定义界限
        int numEle = m*n; //矩阵中的元素个数
        int left = 0,top = 0;
        int right = n - 1,bottom = m - 1;
        // 按照元素个数进行4个方向的遍历
        while(numEle){
            // 上行从左到右,固定top行,遍历[left,right]
            for(int i=left;i<=right&&numEle>0;i++){
                res.push_back(matrix[top][i]);
                numEle--;
            }
            top++;
            // 右列从上到下,固定right列,遍历[top,bottom]
            for(int i=top;i<=bottom&&numEle>0;i++){
               res.push_back(matrix[i][right]);
               numEle--;
            } 
            right--;
            // 下行从右到左,固定bottom行,遍历[right,left]
            for(int i=right;i>=left&&numEle>0;i--){
               res.push_back(matrix[bottom][i]);
               numEle--;
            } 
            bottom--;
            // 左列从下到上,固定left列,遍历[bottom,top]
            for(int i=bottom;i>=top&&numEle>0;i--){
               res.push_back(matrix[i][left]);
               numEle--;
            } 
            left++;
        }
        return res;
    }
};

59. 螺旋矩阵 II(中等难度)

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n,0));// 使用vector定义一个固定长度的二维数组
        int count =1; // 用来给矩阵中每一个空格赋值
        int numEle = n*n; //矩阵中的元素个数
        int left = 0,top = 0;
        int right = n - 1, bottom = n - 1;
        while(numEle>0){
            // 上行从左到右,固定top行,遍历left-right
            for(int i=left;i<=right&&numEle>0;i++){
                res[top][i]=count++;
                numEle--;
            }
            top++;
            // 右列从上到下,固定right列
            for(int i=top;i<=bottom&&numEle>0;i++){
               res[i][right]=count++;
               numEle--;
            } 
            right--;
            // 下行从右到左,固定bottom行
            for(int i=right;i>=left&&numEle>0;i--){
               res[bottom][i]=count++;
               numEle--;
            } 
            bottom--;
            // 左列从下到上,固定left列
            for(int i=bottom;i>=top&&numEle>0;i--){
               res[i][left]=count++;
               numEle--;
            } 
            left++;
        }
        return res;
    }
};