剑指offer19_顺时针打印矩阵_题解

顺时针打印矩阵

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

示例1

输入

[[1,2],[3,4]]

返回值

[1,2,4,3]

分析

方案一:模拟

img

打印方向 1.根据边界打印 2.边界向内收缩 3.是否打印完毕
从左到右 左边界l ,右边界 r 上边界 t 加 1 是否 t > b
从上到下 上边界 t ,下边界b 右边界 r 减 1 是否 l > r
从右到左 右边界 r ,左边界l 下边界 b 减 1 是否 t > b
从下到上 下边界 b ,上边界t 左边界 l 加 1 左边界 l 加 1
/**
时间复杂度:O(MN)
M,N 分别为矩阵行数和列数。
空间复杂度:O(1)
四个边界 l , r , t , b 使用常数大小的 额外 空间( res 为必须使用的空间)。
**/
class Solution
{
public:
    vector<int> printMatrix(vector<vector<int>> &matrix)
    {
        if (matrix.empty())
            return {};
        vector<int> res;
        int l = 0;                    //左边界
        int r = matrix[0].size() - 1; //右边界
        int t = 0;                    //上边界
        int b = matrix.size() - 1;    //下边界
        while (true)
        {
            //left->right
            for (int i = l; i <= r; i++)
                res.push_back(matrix[t][i]);
            // 边界向内收缩
            if (++t > b)
                break;
            //top->bottom
            for (int i = t; i <= b; i++)
                res.push_back(matrix[i][r]);
            if (--r < l)
                break;
            //right->left
            for (int i = r; i >= l; i--)
                res.push_back(matrix[b][i]);
            if (--b < t)
                break;
            //bottom->top
            for (int i = b; i >= t; i--)
                res.push_back(matrix[i][l]);
            if (++l > r)
                break;
        }
        return res;
    }
};

方法二:按层模拟

模拟

fig1

/**
时间复杂度:O(mn),其中 m 和 n 分别是输入矩阵的行数和列数。矩阵中的每个元素都要被访问一次。
空间复杂度:O(1)。除了输出数组以外,空间复杂度是常数。
**/
class Solution
{
public:
    vector<int> printMatrix(vector<vector<int>> &matrix)
    {
        if (matrix.empty())
            return {};

        int rows = matrix.size(), cols = matrix[0].size();
        vector<int> order;
        int left = 0, right = cols - 1, top = 0, bottom = rows - 1;
        while (left <= right && top <= bottom)
        {
            //left->right
            for (int i = left; i <= right; i++)
            {
                order.push_back(matrix[top][i]);
            }
            //top->bottom
            for (int i = top + 1; i <= bottom; i++)
            {
                order.push_back(matrix[i][right]);
            }
            if (left < right && top < bottom)
            {
                //right->left
                for (int i = right - 1; i > left; i--)
                {
                    order.push_back(matrix[bottom][i]);
                }
                //bottom->top
                for (int i = bottom; i > top; i--)
                {
                    order.push_back(matrix[i][left]);
                }
            }
            left++;
            right--;
            top++;
            bottom--;
        }
        return order;
    }
};
posted @ 2020-12-18 17:04  RiverCold  阅读(31)  评论(0编辑  收藏  举报