2713. 矩阵中严格递增的单元格数

题目

给定一个 m x n 的整数矩阵 mat,我们需要找出从某个单元格出发可以访问的最大单元格数量。移动规则是可以从当前单元格移动到同一行或同一列的任何其他单元格,但目标单元格的值必须严格大于当前单元格的值。需要返回最大可访问的单元格数量。

示例

示例 1:

示例1

输入:mat = [[3,1],[3,4]]

输出:2

解释:从第 1 行、第 2 列的单元格开始,可以访问 2 个单元格。

示例 2:

示例2

输入:mat = [[1,1],[1,1]]

输出:1

解释:由于目标单元格必须严格大于当前单元格,只能访问 1 个单元格。

示例 3:

示例3

输入:mat = [[3,1,6],[-9,5,7]]

输出:4

解释:从第 2 行、第 1 列的单元格开始,可以访问 4 个单元格。

提示

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n <= 10^5
  • 1 <= m * n <= 10^5
  • -10^5 <= mat[i][j] <= 10^5

解决方案

采用深度优先搜索(DFS)结合动态规划(DP)来解决此问题。用 dp[i][j] 表示从位置 (i, j) 出发可以访问的最大单元格数。

代码

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>#define MAX(a,b) ((a) > (b) ? (a) : (b))int matSize, matColSize;
int **mat, **dp;bool isValid(int x, int y) {return x >= 0 && x < matSize && y >= 0 && y < matColSize;
}int dfs(int x, int y) {if (dp[x][y] != 0) return dp[x][y];int maxLen = 1;for (int col = 0; col < matColSize; col++) {if (col != y && mat[x][col] > mat[x][y]) {maxLen = MAX(maxLen, 1 + dfs(x, col));}}for (int row = 0; row < matSize; row++) {if (row != x && mat[row][y] > mat[x][y]) {maxLen = MAX(maxLen, 1 + dfs(row, y));}}dp[x][y] = maxLen;return maxLen;
}int maxIncreasingCells(int** matrix, int matrixSize, int* matrixColSize){mat = matrix;matSize = matrixSize;matColSize = *matrixColSize;dp = (int**)calloc(matSize, sizeof(int*));for (int i = 0; i < matSize; i++) {dp[i] = (int*)calloc(matColSize, sizeof(int));}int maxCells = 0;for (int i = 0; i < matSize; i++) {for (int j = 0; j < matColSize; j++) {maxCells = MAX(maxCells, dfs(i, j));}}for (int i = 0; i < matSize; i++) {free(dp[i]);}free(dp);return maxCells;
}

实现步骤

1. 初始化和输入处理

读取输入矩阵,并初始化 dp 数组。dp[i][j] 用于存储从位置 (i, j) 出发可以访问的最大单元格数。

int matSize, matColSize;
int **mat, **dp;dp = (int**)calloc(matSize, sizeof(int*));
for (int i = 0; i < matSize; i++) {dp[i] = (int*)calloc(matColSize, sizeof(int));
}

2. 定义有效移动检查函数

检查从当前单元格移动到目标单元格是否合法,即目标单元格的值必须严格大于当前单元格的值。

bool isValid(int x, int y) {return x >= 0 && x < matSize && y >= 0 && y < matColSize;
}

3. 深度优先搜索(DFS)

  • dp[x][y] 已计算,直接返回。
  • 遍历同一行和同一列中的单元格,若满足条件,递归计算并更新 dp[x][y]
int dfs(int x, int y) {if (dp[x][y] != 0) return dp[x][y];int maxLen = 1;// 遍历同一行中的其他单元格for (int col = 0; col < matColSize; col++) {if (col != y && mat[x][col] > mat[x][y]) {maxLen = MAX(maxLen, 1 + dfs(x, col));}}// 遍历同一列中的其他单元格for (int row = 0; row < matSize; row++) {if (row != x && mat[row][y] > mat[x][y]) {maxLen = MAX(maxLen, 1 + dfs(row, y));}}dp[x][y] = maxLen;return maxLen;
}

4. 主逻辑

  • 遍历矩阵每个单元格,计算从每个单元格出发可以访问的最大单元格数。
  • 更新并返回全局最大值。
int maxIncreasingCells(int** matrix, int matrixSize, int* matrixColSize){mat = matrix;matSize = matrixSize;matColSize = *matrixColSize;dp = (int**)calloc(matSize, sizeof(int*));for (int i = 0; i < matSize; i++) {dp[i] = (int*)calloc(matColSize, sizeof(int));}int maxCells = 0;// 遍历每个单元格for (int i = 0; i < matSize; i++) {for (int j = 0; j < matColSize; j++) {maxCells = MAX(maxCells, dfs(i, j));}}for (int i = 0; i < matSize; i++) {free(dp[i]);}free(dp);return maxCells;
}

复杂度分析

  • 时间复杂度:O(m * n),每个单元格只被访问一次。
  • 空间复杂度:O(m * n),用于存储 dp 数组。

结果

我尽力了。。。不愧是困难提题目
在这里插入图片描述

贴一个优化前的代码

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX(a,b) ((a) > (b) ? (a) : (b))
int gotoNext(int** dp, int matSize, int* matColSize, int** mat, int beginCol, int beginRow, int* tmpStepCnt, bool** isVisited)
{if(dp[beginCol][beginRow] != 0){(*tmpStepCnt) += dp[beginCol][beginRow];return (*tmpStepCnt);}(*tmpStepCnt)++;isVisited[beginCol][beginRow] = true;int tmp_left = 0, tmp_right = 0, tmp_up = 0, tmp_down = 0;int left = 0, right = 0, up = 0, down = 0;int cnt = 0;for (int i = 1; i < matSize; i++){if(beginCol + i <= matSize - 1 && !isVisited[beginCol + i][beginRow] && mat[beginCol + i][beginRow] > mat[beginCol][beginRow]) {tmp_right = gotoNext(dp, matSize, matColSize, mat, beginCol + i, beginRow, &cnt, isVisited);right = MAX(tmp_right, right);cnt = 0;// printf("right = %d\n",right);}else{// // printf("cant goto [%d][%d]\n",beginCol + i, beginRow);}if(beginCol - i >= 0 && !isVisited[beginCol - i][beginRow] && mat[beginCol - i][beginRow] > mat[beginCol][beginRow]) {tmp_left = gotoNext(dp, matSize, matColSize, mat, beginCol - i, beginRow, &cnt, isVisited);left = MAX(tmp_left, left);cnt = 0;// printf("left = %d\n",left);}else{// // printf("cant goto [%d][%d]\n",beginCol - i, beginRow);}}for (int i = 1; i < (*matColSize); i++){if(beginRow + i <= (*matColSize) - 1 && !isVisited[beginCol][beginRow + i] && mat[beginCol][beginRow + i] > mat[beginCol][beginRow]) {tmp_down = gotoNext(dp, matSize, matColSize, mat, beginCol, beginRow + i, &cnt, isVisited);down = MAX(tmp_down, down);cnt = 0;// printf("down = %d\n",down);}else{// // printf("cant goto [%d][%d]\n",beginCol, beginRow + i);}if(beginRow - i >= 0 && !isVisited[beginCol][beginRow - i] && mat[beginCol][beginRow - i] > mat[beginCol][beginRow]){tmp_up = gotoNext(dp, matSize, matColSize, mat, beginCol, beginRow - i, &cnt, isVisited);up = MAX(tmp_up, up);cnt = 0;// printf("up = %d\n",up);}else{// // printf("cant goto [%d][%d]\n",i, beginRow - i);}}isVisited[beginCol][beginRow] = false;(*tmpStepCnt) += MAX(MAX(left, right), MAX(up, down));return (*tmpStepCnt);
}int maxIncreasingCells(int** mat, int matSize, int* matColSize){int stepCnt = 0;int **dp = (int**)calloc(matSize, sizeof(int*)); // 记录从某个格子开始走,可以走多少个格子。bool **isVisited = (bool**)calloc(matSize, sizeof(bool*)); // 记录某个格子是否被访问,防止死循环。for (int i = 0; i < matSize; i++){dp[i] = (int*)calloc((*matColSize), sizeof(int)); // 记录从某个格子开始走,可以走多少个格子。isVisited[i] = (bool*)calloc((*matColSize), sizeof(bool)); // 记录某个格子是否被访问,防止死循环。}for (int i = 0; i < matSize; i++){for (int j = 0; j < (*matColSize); j++){int tmpStepCnt = 0;tmpStepCnt = gotoNext(dp, matSize, matColSize, mat, i, j, &tmpStepCnt, isVisited);stepCnt = MAX(tmpStepCnt, stepCnt);dp[i][j] = tmpStepCnt;// printf("dp[%d][%d] = %d\n", i,j,dp[i][j]);}}return stepCnt;
}

这个更惨,
在这里插入图片描述

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

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

相关文章

服务器流量收发测试

文章目录 一、概述二、实现方式一&#xff1a;编码1. 主要流程2. 核心代码3. 布署 三、实现方式二&#xff1a;脚本1.脚本编写2. 新增crontab任务 四、查看结果 一、概述 我们在安装vnStat、wondershaper便想通过实际的数据收发来进行测试。 二、实现方式一&#xff1a;编码 …

C#客户端

控件 打开链接 Socket socket; // 打开连接 private void button1_Click(object sender, EventArgs e) {button1.Enabled false;button2.Enabled true;//1 创建socket客户端对象socket new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 2…

ChatGPT 提示词技巧一本速通

目录 一、基本术语 二、提示词设计的基本原则 三、书写技巧 2.1 赋予角色 2.2 使用分隔符 2.2 结构化输出 2.3 指定步骤 2.4 提供示例 2.5 指定长度 2.6 使用或引用参考文本 2.7 提示模型进行自我判断 2.8 思考问题的解决过程 ​编辑 2.10 询问是否有遗漏 2.11 …

Studio One 6中文官网下载-Studio One软件下载-音乐编曲软件下载安装

​众多使用者向我们证明了轨道预设保存并调用您喜欢的曲目设置的快照&#xff0c;将您的工作流程效率升级到最新水平&#xff01;存储指定轨道或频道的每项设置&#xff0c;以便即时调用&#xff0c;即使对于多个选定的曲目/频道也同样支持&#xff0c;轨道预设可存储轨道延迟、…

多处理系统结构

目录 统一内存访问&#xff08;UMA&#xff09;多处理器系统结构 优点 缺点 应用场景 UMA 结构的架构示例 解决方案和改进 非统一内存访问&#xff08;NUMA&#xff09;多处理系统结构 概述 NUMA的优点 NUMA的缺点 NUMA系统的工作原理 NUMA优化策略 结论 现代计算…

如何将本地代码上传到git上面

精简步骤&#xff1a; git init git add . git commit -m "first init" git remote add origin 远程仓库地址 git push -u origin master 目录 1、初始化本地仓库 2、添加所有文件到本地仓库 3、提交更改到本地仓库 4、添加github仓库作为远程仓库 5、推送更改…

洛谷:P5704【深基2.例6】字母转换

1. 题目链接 https://www.luogu.com.cn/problem/P5704 【深基2.例6】字母转换 2. 题目描述 输入一个小写字母&#xff0c;输出它的大写 输入&#xff1a;一个小写字母 输出&#xff1a;小写字母的大写形式 3. 我的思考 ASCII码的使用 4. 我提交的题解 /* https://www.luogu…

国际期货投机交易的常见操作方法:

一、在开仓阶段&#xff0c;入市时机的选择&#xff1a; &#xff08;1&#xff09;通过基本分析法&#xff0c;判断市场处于牛市还是熊市 开仓阶段&#xff0c;入市时机的选择&#xff1a;当需求增加、供给减少&#xff0c;此时价格上升&#xff0c;买入期货合约&#xff1b…

# 消息中间件 RocketMQ 高级功能和源码分析(五)

消息中间件 RocketMQ 高级功能和源码分析&#xff08;五&#xff09; 一、 消息中间件 RocketMQ 源码分析&#xff1a;NameServer 路由元数据 1、消息中间件 RocketMQ 中&#xff0c;NameServer 路由管理 NameServer 的主要作用是为消息的生产者和消息消费者提供关于主题 To…

SQL_CALC_FOUND_ROWS 和 FOUND_ROWS()实现对复杂sql实现分页与总条数查询

需求 ReturnResult result new ReturnResult(); try {List<Map> forList (List<Map>) dao.findForList("Mapper.getList", map);int count (int) dao.findForObject("Mapper.getCount", map);result.setData(forList);result.setCode(0);r…

一个小的画布Canvas页面,记录点的轨迹

Hello大家好&#xff0c;好久没有更新了&#xff0c;最近在忙一些其他的事&#xff0c;今天说一下画布canvas&#xff0c;下面是我的代码&#xff0c;实现了一个点从画布的&#xff08;0,0&#xff09;到&#xff08;canvas.width&#xff0c;canvas.height&#xff09;的一个实…

60.指针数组和数组指针

一.指针数组 指针数组是一个数组&#xff0c;在指针数组中存放的是指针变量。 定义一个指针数组p int *p[5]; 内存模型如下&#xff1a; 指针数组的初始化 #include <stdio.h>int main(void) {int a1;int b2;int c3;int i;int *p[3] {&a,&b,&c};for(i0…

椭圆的标准方程与协方差矩阵的特征值和特征向量的关系

椭圆的标准方程与协方差矩阵的特征值和特征向量的关系 flyfish 单位圆 &#xff1a;单位圆表示在标准正交基下的分布。 椭圆 &#xff1a;通过协方差矩阵的特征向量和特征值变换得到的椭圆&#xff0c;表示数据在新的坐标系下的分布。 特征向量 &#xff1a;红色箭头表示特征…

一文学会linux vim操作

Linux Vim操作教程及常用命令 Vim操作教程Vim的模式Vim有三种主要模式&#xff1a;启动Vim文件操作插入文本或新建行移动光标 Vim常用命令查找命令复制、粘贴和撤销替换模式快捷键 Vim操作教程 Vim的模式 Vim有三种主要模式&#xff1a; 正常模式&#xff08;Normal Mode&am…

Android sensor列表和访问记录

命令: dumpsys sensorservice 1.dumpsys sensorservice查看最近申请记录 dumpsys sensorservice命令输出Previous Registrations. Previous Registrations: 23:07:43 0x00000008 pid16587 uid10397 packagecom.start.testdemo.ui.udfp.fql.XsqFQLActivity samplingPeriod66…

07.MyBatis映射器:一对一关联查询

大家好&#xff0c;我是王有志&#xff0c;一个分享硬核 Java 技术的金融摸鱼侠&#xff0c;欢迎大家加入 Java 人自己的交流群“共同富裕的 Java 人”。 《MyBatis 映射器&#xff1a;实现简单的 SQL 语句》中&#xff0c;我们在 MyBatis 映射器的查询语句中使用 resultType 元…

AMBA-CHI协议详解(四)

《AMBA 5 CHI Architecture Specification》 AMBA-CHI协议详解&#xff08;一&#xff09; AMBA-CHI协议详解&#xff08;二&#xff09; AMBA-CHI协议详解&#xff08;三&#xff09; AMBA-CHI协议详解&#xff08;四&#xff09; 文章目录 2.3.3 Atomic transactions2.3.4 S…

Netgen/NGSolve安装

1、安装 1.1、准备 Visual Studio 2022、Python 3、Cmake、Git 1.2、目录 在netgen下有三个文件夹分别是 src、build、install 1.3、安装编译 git clone --recurse-submodules https://github.com/NGSolve/ngsolve.git srccd src git submodule update --init --recursiv…

数据结构-二叉搜索树

二叉搜索树&#xff1a;BST(Binary Search Tree) 二叉搜索树是二叉树&#xff0c;可以为空&#xff0c;如果不为空&#xff0c;满足以下性质&#xff1a; 非空左子树的所有键值小于其根节点的键值非空右子树的所有键值大于其根节点的键值左、右字数本身也都是二叉搜索树 二叉…

使用SSL协议后为什么还要对数据加密后再传输?

使用SSL协议后服务器还是需要对数据 进行对应的加密的。根证书&#xff1a;SSL协议最重要的CA机构在电脑预装的根证书&#xff0c;这个根证书是用于检验网站的数字证书是否正常是否是经过官网备案的防止盗版网站情况。 网站的数字证书数据&#xff1a;网站的基本信息(CA信息、网…