LC 对角线遍历

news2024/9/30 9:24:17

LC 对角线遍历

题目描述:

给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。

题目实例:

示例一:

在这里插入图片描述

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

示例二:
输入:mat = [[1,2],[3,4]]
输出:[1,2,3,4]

提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 104
1 <= m * n <= 104
-105 <= mat[i][j] <= 105

审题:

本题对空间复杂度无要求,我们可以申请额外的空间来解题。

标准思路:

仔细观察我们发现偶数对角线向上遍历,奇数列向下遍历,所以我们的代码就可以按照这个思路遍历。

(1)先得出遍历的次数,也就是对角线的条数为i=n+m-1,所以数组遍历条件也就是i<n+m-1。
(2)在看图,对角线上的每个元素坐标之和为i,也就是元素的坐标xy与i的关系为:x+y=i
(3)如何遍历?看图中,偶数对应的对角线上的元素是从下往上遍历,而奇数对应的对角线上的元素是从上往下遍历,那么只要确定遍历的起始点和结束点就好啦!我们先看偶数对角线的起点和终点,因为奇数对角线和它相反,知道了偶数的,也不难得出奇数的的。

当i<n-1时,起始点坐标x=i,如1的x坐标为0,i也为0,结束点的横坐标x=0
当i>=n-1时,起始点坐标x=n-1,如2的x坐标为2,i也为2,结束点的纵坐标y=m-1,根据(2)中的关系式,所以得出横坐标x=i-(m-1)
所以偶数对角线遍历时起始点的x的坐标为min(i,n-1),结束点的x坐标为max(0,i-(m-1)),而坐标y就是i-x

在这里插入图片描述

代码如下:

#include <vector>

using namespace std;

vector<int> findDiagonalOrder(vector<vector<int>>& mat) {
    // 初始化结果数组
    vector<int> result;
    // 获取矩阵的行数和列数
    int m = mat.size();
    if (m == 0) return result;  // 如果矩阵为空,则直接返回空数组
    int n = mat[0].size();

    // 对角线遍历
    for (int i = 0; i < m + n - 1; ++i) {
        if (i % 2 == 0) {  // 从左上到右下
            // 根据当前对角线的位置,确定遍历的起始点和结束点
            int startX = max(0, i - m + 1);
            int endX = min(i, n - 1);
            // 遍历当前对角线上的元素
            for (int x = startX; x <= endX; ++x) {
                result.push_back(mat[i - x][x]);
            }
        } else {  // 从右下到左上
            // 根据当前对角线的位置,确定遍历的起始点和结束点
            int startX = max(0, i - n + 1);
            int endX = min(i, m - 1);
            // 遍历当前对角线上的元素
            for (int x = startX; x <= endX; ++x) {
                result.push_back(mat[x][i - x]);
            }
        }
    }

    // 返回结果数组
    return result;
}

我的解题思路:

我一开始没有看出奇偶数对角线的特点,注意力全放在了如何遍历的方向上了,我发现遍历时只需要对矩阵边界上的数据做处理,矩阵内的数据只要按照上次遍历的方向走就行了,于是我定义了四个bool类型的变量flag来记录上一次遍历的方向,如果是边界上的数据就进行转弯,如果是矩阵内的数据就按照上一次的遍历方向进行就可以了;当然还需要对一些特殊矩阵做出特殊的处理。代码如下:

#include <iostream>
#include <vector>

using namespace std;

vector<int> findDiagonalOrder(vector<vector<int>> &mat)
{
    int row = mat.size();
    int columns = mat[0].size();
    int i = 0, j = 1, r = 1;
    vector<int> answer;
    bool lowerLeft = false, right = false, upperRight = false, down = false;

    answer.resize(row * columns);

    answer[0] = mat[0][0];
    right = true;

    if (row == 1 && columns == 1)
    {
        return answer;
    }
    else if (row == 1 && columns != 1)
    {
        for (; r < columns; ++r)
        {
            answer[r] = mat[0][r];
        }
        return answer;
    }
    else if (row != 1 && columns == 1)
    {
        for (; r < row; ++r)
        {
            answer[r] = mat[r][0];
        }
        return answer;
    }

    while (i < row && j < columns)
    {
        if (i == 0 && j == columns - 1 && upperRight)
        {
            answer[r++] = mat[i][j];
            ++i;
            down = true, upperRight = false;
        }
        else if (i == 0 && j == columns - 1 && right)
        {
            answer[r++] = mat[i][j];
            ++i, --j;
            lowerLeft = true, right = false;
        }
        else if (i == 0 && right)
        {
            answer[r++] = mat[i][j];
            ++i, --j;
            right = false, lowerLeft = true;
        }
        else if (i == 0 && upperRight)
        {
            answer[r++] = mat[i][j];
            ++j;
            upperRight = false, right = true;
        }
        else if (i == row - 1 && lowerLeft)
        {
            answer[r++] = mat[i][j];
            ++j;
            lowerLeft = false, right = true;
        }
        else if (i == row - 1 && right)
        {
            answer[r++] = mat[i][j];
            --i, ++j;
            right = false, upperRight = true;
        }
        else if (j == 0 && lowerLeft)
        {
            answer[r++] = mat[i][j];
            ++i;
            lowerLeft = false, down = true;
        }
        else if (j == 0 && down)
        {
            answer[r++] = mat[i][j];
            --i, ++j;
            down = false, upperRight = true;
        }
        else if (j == columns - 1 && right)
        {
            answer[r++] = mat[i][j];
            ++i, --j;
            right = false, lowerLeft = true;
        }
        else if (j == columns - 1 && upperRight)
        {
            answer[r++] = mat[i][j];
            ++i;
            upperRight = false, down = true;
        }
        else if (j == columns - 1 && down)
        {
            answer[r++] = mat[i][j];
            ++i, --j;
            down = false, lowerLeft = true;
        }
        else if (lowerLeft)
        {
            answer[r++] = mat[i][j];
            ++i, --j;
        }
        else
        {
            answer[r++] = mat[i][j];
            --i, ++j;
        }
    }

    return answer;
}

int main(int argc, char *argv[])
{
    vector<vector<int>> myVector = {{1, 2, 3, 4, 5}};

    /*
    {{1, 2, 3, 4},
                                        {5, 6, 7, 8},
                                        {9, 10, 11, 12},
                                        {13, 14, 15, 16}}

                                        {{1, 2, 3},
                                    {4, 5, 6},
                                    {7, 8, 9}}
    */
    vector<int> answer;

    for (int i = 0; i < myVector.size(); ++i)
    {
        for (int j = 0; j < myVector[0].size(); ++j)
        {
            cout << myVector[i][j] << " ";
        }
        cout << endl;
    }

    answer = findDiagonalOrder(myVector);

    cout << endl;

    for (int i = 0; i < answer.size(); ++i)
    {
        cout << answer[i] << " ";
    }
    cout << endl;
    return 0;
}
运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1402974.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决Windows下Goland的Terminal设置为Git Bash失败

路径不要选错了&#xff1a; 如果还是不行&#xff1a; 把bash路径加进去试试 goland设置Terminal

华为欧拉操作系统结合内网穿透实现固定公网地址SSH远程连接

文章目录 1. 本地SSH连接测试2. openEuler安装Cpolar3. 配置 SSH公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 欧拉操作系统(openEuler, 简称“欧拉”)是面向数字基础设施的操作系统,支持服务器、云计算、边缘openEuler是面向数字基础设施的操作系…

2.机器学习-K最近邻(k-Nearest Neighbor,KNN)分类算法原理讲解

2️⃣机器学习-K最近邻&#xff08;k-Nearest Neighbor&#xff0c;KNN&#xff09;分类算法原理讲解 个人简介一算法概述二算法思想2.1 KNN的优缺点 三实例演示3.1电影分类3.2使用KNN算法预测 鸢(yuan)尾花 的种类3.3 预测年收入是否大于50K美元 个人简介 &#x1f3d8;️&…

解开缺省参数与函数重载的衣裳

解开缺省参数与函数重载的衣裳 代码是如何由编译器变为可执行文件&#xff1f;预处理 ->编译->汇编->链接预处理编译汇编链接 语法了解缺省参数语法实践语法探究函数重载语法实践语法探究结语 本期和大家一起探究C中的缺省函数与重载函数的语法说明与汇编过程代码是如…

Packet Tracer - 配置第 3 层交换和VLAN间路由

地址分配表 设备 接口 IP 地址/前缀 MLS VLAN 10 192.168.10.254 /24 MLS VLAN 10 2001:db8:acad:10::1/64 MLS VLAN 20 192.168.20.254 /24 MLS VLAN 20 2001:db8:acad:20::1/64 MLS VLAN 30 192.168.30.254/24 MLS VLAN 30 2001:db8:acad:30::1/64 MLS …

某瓜数据app 获取达人直播商品信息接口 Sign

文章目录 声明指定直播间获取商品信息达人主页所有的商品列表接口声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请私信我立即删除! 之前写过:某瓜数据app Sign 具体算法分析请看上一篇,这次看一下不同…

深度学习与大数据在自然语言处理中的应用与进展

引言 在当今社会&#xff0c;深度学习和大数据技术的快速发展为自然语言处理&#xff08;NLP&#xff09;领域带来了显著的进步。这种技术能够使计算机更好地理解和生成人类语言&#xff0c;从而推动了搜索引擎、语音助手、机器翻译等领域的创新和改进。 NLP的发展与技术进步…

golang学习笔记——http.Handle和http.HandleFunc的区别与type func巧妙运用

文章目录 http.Handle和http.HandleFunc的区别http.Handle分析type func巧妙运用 http.HandleFunc分析总结参考资料 http.Handle和http.HandleFunc的区别 http.Handle和http.HandleFunc的区别体现了Go语言接口的巧妙运用 下面代码启动了一个 http 服务器&#xff0c;监听 808…

怎么使用AI人工智能抠图?不妨试试这样做

在数字时代的浪潮中&#xff0c;人工智能技术如春雨般悄然渗透到各个领域&#xff0c;其中尤以图像处理领域为甚。在这场技术的革新中&#xff0c;AI抠图应运而生&#xff0c;它凭借自动识别和提取图像中目标物体的神奇能力&#xff0c;成为图像处理领域的璀璨新星。通过背景与…

编程和数值计算平台:MATLAB R2023a(Win/Mac)激活版

MATLAB R2023a是一款强大的数值计算和科学编程软件&#xff0c;广泛应用于工程、科学和数学领域。 win版&#xff1a;https://soft.macxf.com/soft/3541.html?idMzE5MTM%3D mac版&#xff1a;https://www.macz.com/mac/9321.html?idOTI2NjQ5Jl8mMjcuMTg2LjkuOTg%3D 以下是MAT…

EtherNet/IP开发:C++开发CIP源代码

① 介绍一下CIP CIP是一种考虑到自动化行业而设计的通用协议。然而&#xff0c;由于其开放性&#xff0c;它可以并且已经应用于更多的领域。CIP网络库包含若干卷&#xff1a; 第1卷介绍了适用于所有网络自适应的CIP的常见方面。本卷包含通用对象库和设备配置文件库&#xff0…

Linux与windows互相传输文件之rzsz命令

文章目录 关于rzsz安装软件使用命令方法一&#xff1a;直接拖拽方法二&#xff1a;直接在终端输入rz 关于rzsz 这个工具用于 windows 机器和远端的 Linux 机器通过 XShell 传输文件 安装完毕之后可以通过拖拽的方式将文件上传过去 首先看一下我们的机器可以使用网络吗&#xff…

Spring Boot 4.0:构建云原生Java应用的前沿工具

目录 前言 Spring Boot简介 Spring Boot 的新特性 1. 支持JDK 17 2. 集成云原生组件 3. 响应式编程支持 4. 更强大的安全性 5. 更简化的配置 Spring Boot 的应用场景 1. 云原生应用开发 2. 响应式应用程序 3. 安全性要求高的应用 4. JDK 17的应用 总结 作…

IS-IS:01 ISIS基本配置

这是实验拓扑&#xff0c;下面是基本配置&#xff1a; R1: sys sysname R1 user-interface console 0 idle-timeout 0 0 int loop 0 ip add 1.1.1.1 24 int g0/0/0 ip add 192.168.12.1 24 qR2: sys sysname R2 user-interface console 0 idle-timeout 0 0 int loop 0 ip add …

网络安全的信息收集方法有哪些?

网络安全攻击中的信息收集是攻击者为了了解目标系统的弱点、配置、环境和潜在的防御措施而进行的活动。以下是一些常见的信息收集手段&#xff1a; 开放网络资源查询&#xff1a; 使用搜索引擎查找关于目标组织的信息&#xff0c;包括新闻稿、社交媒体帖子、官方网站等。通过W…

c语言小游戏之扫雷

目录 一&#xff1a;游戏设计理念及思路 二&#xff1a;初步规划的游戏界面 三&#xff1a;开始扫雷游戏的实现 注&#xff1a;1.创建三个文件&#xff0c;test.c用来测试整个游戏的运行&#xff0c;game.c用来实现扫雷游戏的主体&#xff0c;game.h用来函数声明和包含头文…

使用Rancher管理Kubernetes集群

部署前规划 整个部署包括2个部分&#xff0c;一是管理集群部署&#xff0c;二是k8s集群部署。管理集群功能主要提供web界面方式管理k8s集群。正常情况&#xff0c;管理集群3个节点即可&#xff0c;k8s集群至少3个。本文以3节点管理集群&#xff0c;3节点k8s集群为例 说明部署过…

flink部署模式介绍

在一些应用场景中&#xff0c;对于集群资源分配和占用的方式&#xff0c;可能会有特定的需求。Flink 为各种场景提供了不同的部署模式&#xff0c;主要有以下三种&#xff0c;它们的区别主要在于&#xff1a; 集群的生命周期以及资源的分配方式&#xff1b;应用的 main 方法到…

All the stories begin at installation

Before installation, there are some key points about Conan: “Conan is a dependency and package manager for C and C languages.”“With full binary management, Conan can create and reuse any number of different binaries (for different configurations like a…

实时asr新服务串讲

1.背景及现状 工程方面目前语音相关服务存在大量重复代码&#xff0c;逻辑复杂&#xff0c;文档缺失&#xff0c;并且某些细节设计不合理。基于目前现状&#xff0c;代码业务与功能耦合严重&#xff0c;迭代困难&#xff0c;将来增加新的能力也需要改动音频数据相关代码&#x…