Leetcode 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


思路

我是直接模拟的,想象一个机器人从 [0, 0] 位置开始走,初始方向向右,每当他遇到下列情况之一,就改变方向:

  • 按照原方向走,下一步会越界
  • 按照原方向走,下一步是已走过的地方

方向改变的规则是按照右、下、左、上的次序依次循环。

以下是具体实现:

  • 每调用一次 traverse 函数,机器人先将当前格的数字填入答案,然后前进一步,并修改当前所在坐标
  • 使用 traversed 矩阵来记录机器人走过的坐标
  • 一共需要走 m ∗ n m*n mn 步,所以需要调用 m ∗ n m*n mntraverse 函数

时间复杂度: O ( m n ) O(mn) O(mn)
空间复杂度: O ( m n ) O(mn) O(mn)

C++ 代码

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (matrix.empty() || matrix[0].empty())
            return vector<int>();
        const int Y = matrix.size(), X = matrix[0].size();
        vector<vector<bool>> traversed(Y, vector<bool>(X, false));
        vector<int> ans;
        int y = 0, x = 0, direct = 0, sz = Y * X;
        for (int i = 0; i < sz; ++i)
            traverse(matrix, traversed, Y, X, y, x, direct, ans);
        return ans;
    }

    void traverse(vector<vector<int>>& matrix, vector<vector<bool>>& traversed,
            const int Y, const int X, int& y, int& x,
            int& direct, vector<int>& ans) {
        traversed[y][x] = true;
        ans.push_back(matrix[y][x]);
        int nextY = y + direction[direct][0];
        int nextX = x + direction[direct][1];
        if (nextY < 0 || nextY >= Y || nextX < 0 || nextX >= X
                || traversed[nextY][nextX]) {
            direct = (direct + 1) % 4;
            nextY = y + direction[direct][0];
            nextX = x + direction[direct][1];
        }
        y = nextY;
        x = nextX;
    }

private:
    const vector<vector<int>> direction{
        {0, 1},
        {1, 0},
        {0, -1},
        {-1, 0},
    };
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值