对角线遍历 - - - 领扣(leetcode) C++

给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。

 

示例:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

输出:  [1,2,4,7,5,3,6,8,9]

解释:

 

说明:

  1. 给定矩阵中的元素总数不会超过 100000 。

分析:

        读取一个数字后就计算下一个数字的坐标,然后循环读取,直到结束

        首先确定如图所示的箭头走向,要么是左上,要么是右下

        如果一直按照箭头的走向,那么一定会越界,所以需要对越界的情况进行区分,针对不同的区域对坐标进行不同的调整
//         1    2   3
//         8 矩阵 4
//         8 区域 4
//         7    6   5

              

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
//         将整个矩阵区域分为一个九宫格,矩阵区域为0
//         1   2  3
//         8 矩阵 4
//         8 区域 4
//         7   6  5
//         保存结果
        vector<int>result;
//         判空
        if(matrix.empty())
            return result;
//         表示x和y的范围
        int x_range = matrix[0].size();
        int y_range = matrix.size();
//         表示往左上还是右下
        int direction = 1;
//         表示运行到右下角三角形
//      bool flag = false;
//         表示当前坐标
        int x=0,y=0;
//         计数
        int count = 0;
//         直到遍历到最后一个元素
        while(count<x_range*y_range){
            count ++;
            result.push_back(matrix[y][x]);
            // cout<<matrix[y][x]<<endl;
//             **** 计算下一个数字坐标 ***
//             x和y的方向是反的
            x += direction;
            y -= direction;
//             得到坐标区域
            int location = verditc(x_range,x,y_range,y);
            switch(location){
//      |--------------------> x
//      |   1   2  3
//      |   8 矩阵 4
//      |   8 区域 4
//      |   7   6  5
//      v
//      y
//             判断越界和方向
                case 2:
                    y += 1; 
                    direction *= -1;
                    break;
                case 3:
                    x -= 1;
                    y += 2;
                    direction *= -1;
                    break;
                case 4:
                    x -= 1;
                    y += 2;
                    direction *= -1;
                    break;
                case 6:
                    x += 2;
                    y -= 1;
                    direction *= -1;
                    break;
                case 7:
                    x += 2;
                    y -= 1;
                    direction *= -1;
                    break;
                case 8:
                    x += 1;
                    direction *= -1;
                    break;
                case 1:case 5:
//                     不可能出现
                    break;
                case 0:
                    break;
                default:
                    break;
            }
        }
        return result;
    }
    
//     九宫格区域判断
    int verditc(int range_x, int x, int range_y, int y){
        int location = 0;
//         1   2  3
//         8 矩阵 4
//         8 区域 4
//         7   6  5
        if(x < 0){
            if(y < 0)
                location = 1;
            else if(y >= range_y)
                location = 7;
            else
                location = 8;
        }else if(x >= range_x){
            if(y < 0)
                location = 3;
            else if(y >= range_y)
                location = 5;
            else
                location = 4;
            
        }else{
            if(y < 0)
                location = 2;
            else if(y >= range_y)
                location = 6;
            else
                location = 0;
            
        }
        return location;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值