LeetCode 题解 | 498. 对角线遍历(类似螺旋矩阵 C++)

题目描述(中等难度)

原题链接
在这里插入图片描述

算法

(模拟) O ( n m ) O(n*m)
相似的题目有:54. 螺旋矩阵
LeetCode 54,59,885题解 | 螺旋矩阵I,II,II(蛇形矩阵 C++代码)

  • 遍历过程中只有四个方向,而且是按顺序选择方向的
  • 我们将做n*m次循环
  • 每次循环先把当前可走的点加到res中
  • 然后利用(a,b)找到下一个可以走的点
  • 再让(x,y)变成下一个可走的点,然后进入下一个循环
  • 由于往右和往下的方向每次最多走一次,所以每次循环结束后我们要提前改变一次方向,这样下次循环会在对角线方向找下个可行点

注意:最后一次循环只要把点加到res后,就要break,因为最后一点的已经找不到下一个可走的点了

代码1和代码2思路是一样的,只不过空间复杂度上稍微有点不同

C++代码1

时间复杂度是 O ( n m ) O(n*m) ,空间复杂度是 O ( n m ) O(n*m) :用了一个st来标记

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
        if(!matrix.size() || !matrix[0].size()) return {};
        int n = matrix.size(), m = matrix[0].size();
        vector <int> res;
        vector<vector<bool>> st(n, vector<bool>(m, 0));
        int dx[] = {0, 1, 1, -1}, dy[] = {1, -1, 0, 1};

        int x = 0, y = 0, d = 0;
        for (int i = 1; i <= n * m; i ++) {
            res.push_back(matrix[x][y]);
            st[x][y] = true;

            if (i == n * m) break;
            // 利用(a,b)找到下一个可以走的点
            int a = x + dx[d], b = y + dy[d];
            while(a < 0 || a >= n || b < 0 || b >= m || st[a][b] == true) {
                d = (d + 1) % 4;
                a = x + dx[d], b = y + dy[d];
            }

            // 让(x,y)变成下一个可走的点,然后进入下一个循环
            x = x + dx[d];
            y = y + dy[d];
			
			// 往右和往下的方向每次最多走一次,所以要提前改变一次方向
            if (d == 0 || d == 2) d = (d + 1) % 4;
        }

        return res;
    }
};

C++代码2

时间复杂度是 O ( n m ) O(n*m) ,空间复杂度是 O ( 1 ) O(1) :直接利用改matrix的值来判断是否遍历过

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
        if(!matrix.size() || !matrix[0].size()) return {};
        int n = matrix.size(), m = matrix[0].size();
        vector <int> res;
        
        int dx[] = {0, 1, 1, -1}, dy[] = {1, -1, 0, 1};

        int x = 0, y = 0, d = 0;
        for (int i = 1; i <= n * m; i ++) {
            res.push_back(matrix[x][y]);
            matrix[x][y] = INT_MAX;

            if (i == n * m) break;
            // 利用(a,b)找到下一个可以走的点
            int a = x + dx[d], b = y + dy[d];
            while(a < 0 || a >= n || b < 0 || b >= m || matrix[a][b] == INT_MAX) {
                d = (d + 1) % 4;
                a = x + dx[d], b = y + dy[d];
            }

            // 让(x,y)变成下一个可走的点,然后进入下一个循环
            x = x + dx[d];
            y = y + dy[d];
            if (d == 0 || d == 2) d = (d + 1) % 4;
        }

        return res;
    }
};

写在最后:我的博客主要是对计算机领域所学知识的总结、回顾和思考,把每篇博客写得通俗易懂是我的目标,分享技术和知识是一种快乐 ,非常欢迎大家和我一起交流学习,有任何问题都可以在评论区留言,也期待与您的深入交流(^∀^●)

发布了245 篇原创文章 · 获赞 89 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_43827595/article/details/104347157