LeetCode Spiral Matrix

54. Spiral Matrix

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

Example 1:

Input:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
Output: [1,2,3,6,9,8,7,4,5]

Example 2:

Input:
[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9,10,11,12]
]
Output: [1,2,3,4,8,12,11,10,9,5,6,7]

把矩阵按螺旋形打印出来,很有意思的一道题,我隐隐约约记得本科找工作的时候有这么一道笔试题。中等难度,需要多次调试修改才能AC。
思路是标记矩阵的左上角和右下角两个坐标,分别为sx,sy和tx,ty。然后每次从左上角开始,绕一圈,则起点sx,sy都加1,终点tx,ty都减1。如此循环,直到终点跑到起点上面去了。
需要注意后两个for循环的条件,要依次同时满足上一个条件,因为有可能遇到行向量(第三个for)或者列向量(第四个for)。完整代码如下:

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int> >& matrix)
    {
        vector<int> vSpiralOrder;
        if (matrix.size() == 0)
            return vSpiralOrder;
        int sx = 0, sy = 0, tx = matrix.size(), ty = matrix[0].size();
        while (true) {
            for (int j = sy; j < ty; j++)
                vSpiralOrder.push_back(matrix[sx][j]);
            for (int i = sx + 1; i < tx; i++)
                vSpiralOrder.push_back(matrix[i][ty – 1]);
            for (int j = ty – 2; sx + 1 < tx && j >= sy; j–) // 满足上一个条件sx+1<tx
                vSpiralOrder.push_back(matrix[tx – 1][j]);
            for (int i = tx – 2; ty – 2 >= sy && i > sx; i–) // 满足上一个条件ty-2>=sy
                vSpiralOrder.push_back(matrix[i][sy]);
            sx++;
            sy++;
            tx–;
            ty–;
            if (sx >= tx || sy >= ty)
                break;
        }
        return vSpiralOrder;
    }
};

本代码提交AC,用时0MS。

二刷。更安全的做法(https://discuss.leetcode.com/topic/3713/super-simple-and-easy-to-understand-solution):

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int> >& matrix)
    {
        vector<int> ans;
        if (matrix.empty() || matrix[0].empty())
            return ans;
        int start_row = 0, start_col = 0, end_row = matrix.size() – 1, end_col = matrix[0].size() – 1;
        while (start_row <= end_row && start_col <= end_col) {
            for (int j = start_col; j <= end_col; ++j) {
                ans.push_back(matrix[start_row][j]);
            }
            ++start_row;
            for (int i = start_row; i <= end_row; ++i) {
                ans.push_back(matrix[i][end_col]);
            }
            –end_col;
            if (start_row <= end_row) { // 防止行向量
                for (int j = end_col; j >= start_col; –j) {
                    ans.push_back(matrix[end_row][j]);
                }
            }
            –end_row;
            if (start_col <= end_col) { // 防止列向量
                for (int i = end_row; i >= start_row; –i) {
                    ans.push_back(matrix[i][start_col]);
                }
            }
            ++start_col;
        }
        return ans;
    }
};

本代码提交AC,用时0MS。

三刷。直接模拟,设置left、right、up、down分别表示向左、右、上、下的结束位置,到达该位置需要换方向,同时更新对应的结束位置。完整代码如下:

class Solution {
public:
	vector<int> spiralOrder(vector<vector<int>>& matrix) {
		vector<int> ans;
		if (matrix.size() == 0)return {};
		int m = matrix.size(), n = matrix[0].size();
		if (m <= 1 || n <= 1) {
			for (int i = 0; i < m; ++i) {
				for (int j = 0; j < n; ++j) {
					ans.push_back(matrix[i][j]);
				}
			}
			return ans;
		}
		int left = 0, right = n - 1, up = 1, down = m - 1;
		int dir = 0, i = 0, j = 0; // dir: 0: right; 1: down; 2: left; 3:up
		int total_num = m * n, cur_num = 0;
		while (cur_num < total_num) {
			ans.push_back(matrix[i][j]);
			++cur_num;
			switch (dir) {
			case 0:
				if (j == right) {
					++i;
					dir = 1;
					--right;
				}
				else {
					++j;
				}
				break;
			case 1:
				if (i == down) {
					--j;
					dir = 2;
					--down;
				}
				else {
					++i;
				}
				break;
			case 2:
				if (j == left) {
					--i;
					dir = 3;
					++left;
				}
				else {
					--j;
				}
				break;
			case 3:
				if (i == up) {
					++j;
					dir = 0;
					++up;
				}
				else {
					--i;
				}
				break;
			}
		}
		return ans;
	}
};

本代码提交AC,用时0MS。

1 thought on “LeetCode Spiral Matrix

  1. Pingback: LeetCode Spiral Matrix II | bitJoy > code

Leave a Reply

Your email address will not be published. Required fields are marked *