zoukankan      html  css  js  c++  java
  • LeetCode54. 螺旋矩阵


    题意是,输入一个二维数组,从数组左上角开始,沿着顺时针慢慢地“遍历”每一个元素且每一个元素只遍历一次,
    在一个新的一维数组中记录遍历的顺序,最终的返回值就是这个数组。
    思路:可以考虑用方向来模拟“一个指针的移动”,指针指向的元素如果合法(不越界且未被访问过),就将这个元素压入结果数组。
    这里的核心是“移动指针”,移动指针要注意两点:

    1. 移动的方向是顺时针:即先往右,再往下,再往左,再往上,再往右。。。。
      这里可以用两个方向数组作辅助,比如原来的坐标是(x, y),那么“往右”可以表示为 newX = x, newY = y + 1.
      也就是说,每次移动一个方向,只是改变x和y的其中一个值,且改变的值可以枚举。
      所以可以用dx表示x的改变: int dx[4] = {0, 1, 0, -1};
      用dy表示y的改变: int dy[4] = {1, 0, -1, 0};
      再用一个整数变量direction表示“当前的方向”,比如direction为0时,dx[direction] = 0, dy[direction] = 1,
      newX = x + dx[direction] = x, newY = y + dy[direction] = y + 1 表示“当前方向向右”
    2. 移动的时候要注意避免“撞墙”,撞墙有两种情况:一种是(newX, newY)越界,一种是(newX, newY)已经访问过了。碰到撞墙,就需要
      再更新一下(newX, newY)(通过改变方向)。
      由于要记录是否访问过,所以要额外再开一个二维数组记录每个位置的元素是否访问过。
      综上,可以得出如下代码:
    class Solution {
    public:
        vector<int> spiralOrder(vector<vector<int>>& matrix) {
            if(matrix.size() == 0 || matrix[0].size() == 0) {           //行数或列数为0的情况需要特判
                return {};
            }
            int rows = matrix.size(), cols = matrix[0].size();           //记录行数和列数
            vector<int> res(rows * cols);                                //res是结果数组
            vector<vector<bool>> visited(rows, vector<bool>(cols));      //记录某个位置的元素是否已访问过
            int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};            
            for(int x = 0, y = 0, direction = 0, cnt = 0; cnt < rows * cols; ++cnt) {      //cnt记录res数组的元素个数,当cnt与matrix元素个数相同时停止更新坐标
                res[cnt] = matrix[x][y];
                visited[x][y] = true;
                int newX = x + dx[direction], newY = y + dy[direction];
                if(newX < 0 || newX >= rows || newY < 0 || newY >= cols || visited[newX][newY] == true) {      //如果“撞墙”,需要再次更新(newX, newY)
                    direction = (direction + 1) % 4;                        //direction只有0 ~ 3 这四种取值,因为只有四个方向!
                    newX = x + dx[direction], newY = y + dy[direction];
                }
                x = newX, y = newY;                                    //更新(x, y)为(newX, newY)
            }
            return res;
        }
    };
    
  • 相关阅读:
    ORM是什么?
    mysql 杂谈
    IO model之IO多路复用的触发方式
    IO model之select poll epoll IO多路复用介绍
    IO model
    事件驱动模型介绍
    函数
    商品程序
    随机生成密码
    import radom 和import string
  • 原文地址:https://www.cnblogs.com/linrj/p/13196060.html
Copyright © 2011-2022 走看看