力扣54和59题
54.顺时针打印矩阵
题目:

思路:将矩阵分为若干层,首先打印最外层的元素,然后一直往里打印
对于每层,从左上方开始以顺时针的顺序遍历所有元素。假设当前层的左上角位于(top,left),右下角位于 (bottom,right),按照如下顺序遍历当前层的元素。
(1)从左到右遍历上侧元素,依次为(top,left) 到(top,right);
(2)从上到下遍历右侧元素,依次为(top+1,right) 到 (bottom,right);
如果 left<right 且top<bottom,则
(3)从右到左遍历下侧元素,依次为(bottom,right−1)到(bottom,left+1);
(4)从下到上遍历左侧元素,依次为(bottom,left)到 (top+1,left)。
遍历完当前层的元素之后,将 left 和 top 分别增加 1,将right 和 bottom 分别减少 1,进入下一层继续遍历,直到遍历完所有元素为止。

C++代码:
//按层模拟
class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (!matrix.size() || !matrix[0].size()) return {};
        vector<int> res;
        int rows = matrix.size();   //最外层行数
        int columns = matrix[0].size(); //最外层列数
        int top = 0, left = 0, bottom = rows - 1, right = columns - 1;  //左上角:[top, left] 右下角:[bottom, right]
        while (left <= right && top <= bottom) {
            //遍历top行:left --> right
            for (int column = left; column <= right; ++column) {
                res.push_back(matrix[top][column]);
            }
            //遍历right列:top+1 --> bottom
            for (int row = top + 1; row <= bottom; ++row) {
                res.push_back(matrix[row][right]);
            }
            //判断是否已经到了最里层
            if (left < right && top < bottom) {
                //遍历bottom行:right-1 --> left+1
                for (int column = right - 1; column > left; --column) {
                    res.push_back(matrix[bottom][column]);
                }
                //遍历left列:bottom --> top+1
                for (int row = bottom; row > top; --row) {
                    res.push_back(matrix[row][left]);
                }
            }
            top++;
            left++;
            bottom--;
            right--;
        }
        return res;
    }
};
59.螺旋矩阵
题目描述:

思路:由于矩阵是n*n的,可以将矩阵分为n/2层来考虑,分层按照顺时针依次填充数字
#include <iostream>
using namespace std;
#include <vector>
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
        int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
        int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
        int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
        int count = 1; // 用来给矩阵中每一个空格赋值
        int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
        int i, j;
        while (loop--) {
            // 下面开始的四个for就是模拟转了一圈
            // 模拟填充上行从左到右(左闭右开)
            for (j = starty; j < n - offset; j++) {
                res[startx][j] = count++;
            }
            // 模拟填充右列从上到下(左闭右开)
            for (i = startx; i < n - offset; i++) {
                res[i][j] = count++;
            }
            // 模拟填充下行从右到左(左闭右开)
            for (; j > starty; j--) {
                res[i][j] = count++;
            }
            // 模拟填充左列从下到上(左闭右开)
            for (; i > startx; i--) {
                res[i][j] = count++;
            }
            // 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
            startx++;
            starty++;
            // offset 控制每一圈里每一条边遍历的长度
            offset += 1;
        }
        // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
        if (n % 2) {
            res[mid][mid] = count;
        }
        return res;
    }
};
int main()
{   
    Solution solution1;
    int n = 5;
    vector<vector<int>> res = solution1.generateMatrix(n);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cout << res[i][j] << " ";
        }
        cout << endl;
    }
}
螺旋矩阵本身不涉及算法,而是考察数据的一种遍历方式



















