leetcode腾讯精选练习之螺旋矩阵(八)

螺旋矩阵

题目

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
    [
         [ 1, 2, 3 ],
         [ 4, 5, 6 ],
         [ 7, 8, 9 ]
    ]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
    [
         [1, 2, 3, 4],
         [5, 6, 7, 8],
         [9,10,11,12]
    ]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]

思路

1.判断矩阵是否为空矩阵,如果为空则直接返回。
2.从左向右遍历,行坐标不变,列坐标从小到大,直至该行遍历结束,然后将行坐标自增并判断矩阵是否遍历结束。
3.从上向下遍历,列坐标不变,行坐标从小到大,直至该列遍历完毕,然后将列坐标自减并判断该矩阵是否遍历结束。
4.从左向右遍历,行坐标不变,列坐标从大到小,直至该行遍历结束,然后将行坐标自减并判断矩阵是否遍历结束。
5.从下向上遍历,列坐标不变,行坐标从大到小,直至该列遍历完毕,然后将该列坐标自增并判断是否遍历结束。
6.依次重复2,3,4,5过程,直至整个矩阵遍历完毕。

代码

vector<int> spiralOrder(vector<vector<int>>& matrix) {
    vector<int> res;
    if (matrix.empty()) return res;
    int beginX = 0;
    int endX = matrix[0].size() - 1;
    int beginY = 0;
    int endY = matrix.size() - 1;
    while (true)
    {
        //从左到右
        for (int i = beginX; i <= endX; i++)
        {
            res.push_back(matrix[beginY][i]);
        }
        if (++beginY > endY)
        {
            break;
        }
        //从上到下
        for (int i = beginY; i <= endY; ++i) {
            res.push_back(matrix[i][endX]);
        }
        if (beginX > --endX)
        {
            break;
        }
        // 从右到左
        for (int i = endX; i >= beginX; --i)
        {
            res.push_back(matrix[endY][i]);
        }
        if (beginY > --endY)
        {
        break;
        }
        // 从下往上
        for (int i = endY; i >= beginY; --i)
        {
            res.push_back(matrix[i][beginX]);
        }
        if (++beginX > endX)
        {
            break;
        }
    }
    return res;
}

总结

1.确定好要遍历的矩阵的左上角和右小角的坐标,即确定每一轮遍历的起点和终点。
2.确定每个过程坐标变换的规律。
3.该题情况多了一些,按照要求一步一步分析,就不会有遗漏。

螺旋矩阵 II

题目

给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3
输出:
    [
         [ 1, 2, 3 ],
         [ 8, 9, 4 ],
         [ 7, 6, 5 ]
    ]

思路

该题的遍历方法与上个题目一样

代码

vector<vector<int>> generateMatrix(int n) {
    vector<vector<int> > res(n, vector<int>(n));
    if (n == 0)
    {
        return res;
    }
    int beginX = 0;
    int endX = n - 1;
    int beginY = 0;
    int endY = n - 1;
    int index = 1;
    while (true) {
        //从左到右
        for (int i = beginX; i <= endX; i++)
        {
            res[beginY][i] = index++;
        }
        if (++beginY > endY)
        {
            break;
        }
        //从上到下
        for (int i = beginY; i <= endY; ++i) {
            res[i][endX] = index++;
        }
        if (beginX > --endX)
        {
            break;
        }
        // 从右到左
        for (int i = endX; i >= beginX; --i)
        {
            res[endY][i] = index++;
        }
        if (beginY > --endY)
        {
            break;
        }
        // 从下往上
        for (int i = endY; i >= beginY; --i)
        {
            res[i][beginX] = index++;
        }
        if (++beginX > endX)
        {
            break;
        }
    }
    return res;
}

总结

偷了个懒,从上个题目直接拷贝过来,修改一下遍历操作,这个题目就完成了。

万变不离其宗,掌握了方法,题目都是一样的

原文地址:https://www.cnblogs.com/zh20130424/p/12247801.html