【map】【动态规划】LeetCode2713:矩阵中严格递增的单元格数

本文涉及的基础知识点

二分查找算法合集

题目

给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat,你可以选择任一单元格作为 起始单元格 。
从起始单元格出发,你可以移动到 同一行或同一列 中的任何其他单元格,但前提是目标单元格的值 严格大于 当前单元格的值。
你可以多次重复这一过程,从一个单元格移动到另一个单元格,直到无法再进行任何移动。
请你找出从某个单元开始访问矩阵所能访问的 单元格的最大数量 。
返回一个表示可访问单元格最大数量的整数。
示例 1:
输入:mat = [[3,1],[3,4]]
输出:2
解释:上图展示了从第 1 行、第 2 列的单元格开始,可以访问 2 个单元格。可以证明,无论从哪个单元格开始,最多只能访问 2 个单元格,因此答案是 2 。
示例 2:
输入:mat = [[1,1],[1,1]]
输出:1
解释:由于目标单元格必须严格大于当前单元格,在本示例中只能访问 1 个单元格。
示例 3:
输入:mat = [[3,1,6],[-9,5,7]]
输出:4
解释:上图展示了从第 2 行、第 1 列的单元格开始,可以访问 4 个单元格。可以证明,无论从哪个单元格开始,最多只能访问 4 个单元格,因此答案是 4 。
参数范围
m == mat.length
n == mat[i].length
1 <= m, n <= 105
1 <= m * n <= 105
-105 <= mat[i][j] <= 105

分析

时间复杂度: O(mnlogmn)。初始化数据时间复杂度:O(nmlogmn)。枚举所有单元格时间复杂度O(mn),处理每个单元格,时间复杂度O(n)。

变量解析

mValueToRowCols各值对应的行列,按值降序排序
vRowMax大于当前值的各行最大递增单元格数
vColMax大于当前值的各列最大递增单元格数
vBuf当前值各行列的最大递增单元格数

代码

class Solution {
public:
	int maxIncreasingCells(vector<vector<int>>& mat) {
		m_r = mat.size();
		m_c = mat.front().size();
		std::map<int, vector<pair<int, int>>,greater<int>> mValueToRowCols;
		for (int r = 0; r < m_r ;r++)
		{
			for (int c = 0; c < m_c ; c++)
			{
				mValueToRowCols[mat[r][c]].emplace_back(r, c);
			}
		}
		vector<int> vRowMax(m_r), vColMax(m_c);
		vector<tuple<int, int, int>> vBuf;
		for (const auto& [tmp, v] : mValueToRowCols)
		{			
			for (const auto& [r, c] : v)
			{
				const int iMax = max(vRowMax[r], vColMax[c]) + 1;
				vBuf.emplace_back(r, c, iMax);				
			}
			for (const auto& [r, c, iMax] : vBuf)
			{
				vRowMax[r] = max(vRowMax[r], iMax);
				vColMax[c] = max(vColMax[c], iMax);
			}
			vBuf.clear();
		}
		return *std::max_element(vRowMax.begin(), vRowMax.end());
	}
	int m_r, m_c;
};

测试用例

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() != v2.size())
	{
		assert(false);
		return;
	}
	for (int i = 0; i < v1.size(); i++)
	{
		assert(v1[i] == v2[i]);
	}
}

template<class T>
void Assert(const T& t1, const T& t2)
{
	assert(t1 == t2);
}

int main()
{
	vector<vector<int>> mat;
	{
		Solution slu;
		mat = { {3,1},{3,4} };
		auto res = slu.maxIncreasingCells(mat);
		Assert(2, res);
	}
	{
		Solution slu;
		mat = { {1,1},{1,1} };
		auto res = slu.maxIncreasingCells(mat);
		Assert(1, res);
	}
	{
		Solution slu;
		mat = mat = { {3,1,6},{-9,5,7} };
		auto res = slu.maxIncreasingCells(mat);
		Assert(4, res);
	}
	{
		Solution slu;
		mat = mat = { {5, 2, 9},{-6, 2, -5},{-1, 0, -5} };
		auto res = slu.maxIncreasingCells(mat);
		Assert(6, res);
	}
}

超时代码示例

vector<int> vRowMax(m_r), vColMax(m_c);
		for (const auto& [tmp, v] : mValueToRowCols)
		{
			vector<int> vCurRowMax = vRowMax, vCurColMax = vColMax;
			for (const auto& [r, c] : v)
			{
				const int iMax = max(vRowMax[r], vColMax[c]) + 1;
				vCurRowMax[r]= max(vCurRowMax[r],iMax);
				vCurColMax[c] = max(vCurColMax[r],iMax);
			}
			vCurRowMax.swap(vRowMax);
			vCurColMax.swap(vColMax);
		}

vector 构造函数比较费事,执行mn次会超时。

2023年6月旧代码

class Solution {
public:
int maxIncreasingCells(vector<vector>& mat)
{
m_r = mat.size();
m_c = mat[0].size();
std::map < int, vector<pair<int, int>>,std::greater> mValueRowCol;
for (int r = 0; r < m_r; r++)
{
for (int c = 0; c < m_c; c++)
{
mValueRowCol[mat[r][c]].emplace_back(make_pair( r, c ));
}
}
vector vPreRows(m_r, 0), vPreCols(m_c, 0);
int iMaxRet = 0;
std::queue<std::tuple<int, int, int> > que;
for ( auto it : mValueRowCol)
{
for (const auto& pr : it.second)
{
int iRet = std::max(vPreRows[pr.first],vPreCols[pr.second])+1 ;
iMaxRet = max(iMaxRet, iRet);
que.emplace(pr.first, pr.second, iRet);
}
while (que.size())
{
const int r = get<0>(que.front());
const int c = get<1>(que.front());
const int iRet = get<2>(que.front());
que.pop();
vPreRows[r] = max(vPreRows[r] ,iRet);
vPreCols[c] = max(vPreCols[c],iRet);
}
}

	return iMaxRet;
}
int m_r, m_c;

};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

群晖(Synology)更换硬盘时间和精神双重折磨的教训

话说玩磁盘阵列的最后结果就是时间上负担不起&#xff0c;并且还被嫌弃。 在磁盘都到位后下一步就是要选择冗余类型了&#xff0c;对大部分人来说使用群晖自己提供的就好了&#xff0c;通常是 SHR。 什么是 SHR Synology Hybrid RAID&#xff08;SHR&#xff09;是 Synology…

为什么要使用国际语音群呼系统?

1.降本增效 通过批量导入客户的电话号码&#xff0c;由系统自动完成批量呼叫&#xff0c;企业可以节省人工拨号的费用&#xff0c;高效助力企业业务增长&#xff1b; 2.降低流失 通过批量群呼&#xff0c;企业可以724小时高并发无故障运行&#xff0c;智能锁定意向客户&…

【c语言】【visual studio】动态内存管理,malloc,calloc,realloc详解。

引言&#xff1a;随着大一期末的到来&#xff0c;想必许多学生都学到内存的动态管理这一部分了&#xff0c;看望这篇博客后&#xff0c;希望能解除你心中对这一章节的疑惑。 (・∀・(・∀・(・∀・*) 1.malloc详解 malloc的头文件是#include <sdtlib.h>,malloc - C Ref…

bugku--文件包含

点击 访问一下index.php 页面报错 既然是文件包含就可以想到php伪协议 这里我们需要访问本地文件系统 构造我们的payload ?filephp://filter/readconvert.base64-encode/resourceindex.php base64解码 得到我们的flag 提交就好啦 ?filephp://filter/readconvert.base64-e…

bugku--source

dirsearch扫一下 题目提示源代码&#xff08;source&#xff09; 也就是源代码泄露&#xff0c;然后发现有.git 猜到是git泄露 拼接后发现有文件 但是点开啥也没有 kali里面下载下来 wegt -r 下载网站的所有内容 ls 查看目录 cd 进入到目录里面 gie reflog 引用日志使用…

过滤(删除)迭代对象中满足指定条件的元素itertools.filterfalse()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 过滤(删除)迭代对象中 满足指定条件的元素 itertools.filterfalse() [太阳]选择题 请问以下代码输出的结果是&#xff1f; a [1, 2, 3, 4, 5] print("【显示】a ",a) import ite…

【SpringBoot】FreeMarker视图渲染

目录 一、FreeMarker 简介 1.1 什么是FreeMarker&#xff1f; 1.2 Freemarker模板组成部分 1.3 为什么要使用FreeMarker 二、Springboot集成FreeMarker 2.1 配置 2.2 数据类型 2.2.1 字符串 2.2.2 数值 2.2.3 布尔值 2.2.4 日期 2.3 常见指令 2.3.2 assign 2.3…

C++ 重载括号运算符示例

重载括号运算符的写法是&#xff0c; 返回值 operator() ( 表达式表 ) 参数个数不限&#xff1b; VC6新建一个单文档工程&#xff1b; 添加一个示例类&#xff0c;比较短&#xff0c;直接加到视类h文件的头部&#xff1b; class A { public:// 重载 括号 () 运算符int oper…

scratch魔法变变变 2023年12月中国电子学会图形化编程 少儿编程 scratch编程等级考试一级真题和答案解析

目录 scratch魔法变变变 一、题目要求 1、准备工作 2、功能实现 二、案例分析

webpack详细教程

1&#xff0c;什么是webpackwebpack | webpack中文文档 | webpack中文网 Webpack 不仅是一个模块打包器(bundler)&#xff0c;更完整的讲是一个前端自动化构建工具。在 Webpack 看来前端的所有资源文件(s/json/css/img/less/...)都会作为横块处理它将根据模块的依赖关系进行静…

进程概念【linux】

进程基础 在学习进程之前&#xff0c;首先要有一定的计算机硬件和软件基础。 硬件基础&#xff1a;冯诺依曼体系结构 如图&#xff0c;是计算机在硬件上的体系结构。 下面举出一些常见的输入输出设备&#xff08;有些设备只作输出设备&#xff0c;或者只作输入设备&#xff…

xtu oj 1328 数码和

题目描述 一个10进制数n在2∼16进制下可以得到的不同的数码和&#xff0c;求在这些数码和中出现次数最多的数码和。 比如20&#xff0c; 其中数码和2和4分别出现了3次&#xff0c;为最多出现次数。 输入 第一行是一个整数T(1≤T≤1000)&#xff0c;表示样例的个数。 以后每行…

【数据结构(十一·多路查找树)】B树、B+树、B*树(6)

文章目录 1. 二叉树 与 B树1.1. 二叉树存在的问题1.2. 多叉树 的概念1.3. B树 的基本介绍 2. 多叉树——2-3树2.1. 基本概念2.2. 实例应用2.3. 其他说明 3. B 树、B树 和 B*树3.1. B树 的介绍3.2. B树 的介绍3.2. B*树 的介绍 1. 二叉树 与 B树 1.1. 二叉树存在的问题 二叉树…

计算机视觉(P2)-计算机视觉任务和应用

一、说明 在本文中&#xff0c;我们将探讨主要的计算机视觉任务以及每个任务最流行的应用程序。 二、图像内容分类 2.1. 图像分类 图像分类是计算机视觉领域的主要任务之一[1]。在该任务中&#xff0c;经过训练的模型根据预定义的类集为图像分配特定的类。下图是著名的CIFAR…

大数据技术之Hive(超级详细)

第1章 Hive入门 1.1 什么是Hive Hive&#xff1a;由Facebook开源用于解决海量结构化日志的数据统计。 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张表&#xff0c;并提供类SQL查询功能。 本质是&#xff1a;将HQL转化成MapReduce程序 …

TensorFlow学习笔记--(4)神经网络模型-数据集预处理

神经网络初步 以scikit-leran鸢尾花为例 通过scikit-learn库自带的鸢尾花数据集 来测试数据的读入 from sklearn import datasets from pandas import DataFrame import pandas as pdx_data datasets.load_iris().data # .data返回iris数据集所有输入特征 y_data dataset…

【51单片机系列】proteus中创建16x16LED点阵

本文参考来源&#xff1a; Proteus8.6中16x16LED点阵制作教程【Proteus】16乘16点阵滚动播放 文章目录 一、测试proteus中的8x8点阵驱动方式1.1 测试电流通过方向1.2 测试行列控制接口 二、使用proteus中的8x8点阵制作16x16LED点阵三、测试制作的16x16LED点阵四、使用自制的16x…

06 python 文件基础操作

6.1 .1文件读取操作 演示对文件的读取 # 打开文件 import timef open(02_word.txt, r, encoding"UTF-8") print(type(f))# #读取文件 - read() # print(f读取10个字节的结果{f.read(10)}) # print(f读取全部字节的结果{f.read()})# #读取文件 - readLines() # lines…

Python——数据库操作

目录 &#xff08;1&#xff09;安装Flask-SQLAlchemy &#xff08;2&#xff09;使用Flask-SQLAlchemy操作数据库 &#xff08;3&#xff09;连接数据库 •创建数据表 •增加数据 •查询数据 •更新数据 •删除数据 Flask-SQLAlchemy是Flask中用于操作关系型数据库的扩展…

JavaEE:单例模式(饿汉模式和懒汉模式)精讲

前言 什么是单例模式&#xff1f; 其实用通俗的话就是程序猿约定俗成的一些东西&#xff0c;就比如如果你继承了一个抽象类&#xff0c;你就要重写里面的抽象方法&#xff0c;如果你实现了一个接口&#xff0c;你就要重写里面的方法。如果不进行重写&#xff0c;那么编译器就会…