【C++二分查找 前缀和 】1292. 元素和小于等于阈值的正方形的最大边长

news2024/12/26 23:01:20

本文涉及的基础知识点

C++二分查找
C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频

LeetCode1292. 元素和小于等于阈值的正方形的最大边长

给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold。
请你返回元素总和小于或等于阈值的正方形区域的最大边长;如果没有这样的正方形区域,则返回 0 。

示例 1:
输入:mat = [[1,1,3,2,4,3,2],[1,1,3,2,4,3,2],[1,1,3,2,4,3,2]], threshold = 4
在这里插入图片描述

输出:2
解释:总和小于或等于 4 的正方形的最大边长为 2,如图所示。
示例 2:
输入:mat = [[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2]], threshold = 1
输出:0
提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 300
0 <= mat[i][j] <= 104
0 <= threshold <= 105

二分查找、前缀和

预处理好前缀和后,可以在O(1)的时间内,计算矩形之和。
二分查找类型:寻找末端
Check函数的参数返回:[1,min(n,m)]
异常处理:如果Check(ret)不成立,则返回0。
Check函数:枚举各矩形的左上角,如果和小于等于阈值,返回true。否则返回false。Check函数的时间复杂度:O(nm)
总时间复杂度:O(log(min(n,m))nm)

代码

核心代码

template<class T = int>
class CPreSum2 {
public:
	template<class _Pr>
	CPreSum2(int rowCnt, int colCount, _Pr pr) :m_iRowCnt(rowCnt), m_iColCnt(colCount) {
		m_vSum.assign(rowCnt + 1, vector<int>(colCount + 1));
		for (int r = 0; r < rowCnt; r++) {
			for (int c = 0; c < colCount; c++) {
				m_vSum[r + 1][c + 1] = m_vSum[r][c + 1] + m_vSum[r + 1][c] - m_vSum[r][c] + pr(r, c);
			}
		}
	}
	T Get(int left, int top, int right, int bottom)const {
		return m_vSum[bottom + 1][right + 1] - m_vSum[top][right + 1] - m_vSum[bottom + 1][left] + m_vSum[top][left];
	}
	T GetTopLeft(int left, int top) { return Get(left, top, m_iColCnt - 1, m_iRowCnt - 1); }
	vector<vector<T>> m_vSum;
	const int m_iRowCnt, m_iColCnt;
};
template<class INDEX_TYPE>
class CBinarySearch
{
public:
	CBinarySearch(INDEX_TYPE iMinIndex, INDEX_TYPE iMaxIndex):m_iMin(iMinIndex),m_iMax(iMaxIndex) {}
	template<class _Pr>
	INDEX_TYPE FindFrist( _Pr pr)
	{
		auto left = m_iMin - 1;
		auto rightInclue = m_iMax;
		while (rightInclue - left > 1)
		{
			const auto mid = left + (rightInclue - left) / 2;
			if (pr(mid))
			{
				rightInclue = mid;
			}
			else
			{
				left = mid;
			}
		}
		return rightInclue;
	}
	template<class _Pr>
	INDEX_TYPE FindEnd( _Pr pr)
	{
		int leftInclude = m_iMin;
		int right = m_iMax + 1;
		while (right - leftInclude > 1)
		{
			const auto mid = leftInclude + (right - leftInclude) / 2;
			if (pr(mid))
			{
				leftInclude = mid;
			}
			else
			{
				right = mid;
			}
		}
		return leftInclude;
	}
protected:
	const INDEX_TYPE m_iMin, m_iMax;
};

class Solution {
		public:
			int maxSideLength(vector<vector<int>>& mat, int threshold) {
				m_r = mat.size();
				m_c = mat.front().size();
				CPreSum2<int> preSum(m_r, m_c, [&](const int& r, const int& c) {return mat[r][c]; });			
				auto Check = [&](int mid) {
					for (int r = 0; r+mid <= m_r; r++) {
						for (int c = 0; c+mid <= m_c; c++) {
							const int sum = preSum.Get(c, r, c + mid - 1, r + mid - 1);
							if (sum <= threshold) { return true; }
						}
					}
					return false;
				};
				return CBinarySearch<int>(0, min(m_r, m_c)).FindEnd(Check);
			}
			int m_r, m_c;
		};

单元测试

	vector<vector<int>> mat;
		int threshold;

		TEST_METHOD(TestMethod13)
		{
			mat = { {1,1,3,2,4,3,2},{1,1,3,2,4,3,2},{1,1,3,2,4,3,2} }, threshold = 4;
			auto res = Solution().maxSideLength(mat, threshold);
			AssertEx(2, res);
		}
		TEST_METHOD(TestMethod14)
		{
			mat = { {2,2,2,2,2},{2,2,2,2,2},{2,2,2,2,2},{2,2,2,2,2},{2,2,2,2,2} }, threshold = 1;
			auto res = Solution().maxSideLength(mat, threshold);
			AssertEx(0, res);
		}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

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

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

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

相关文章

C++ 设计模式——策略模式

策略模式 策略模式主要组成部分例一&#xff1a;逐步重构并引入策略模式第一步&#xff1a;初始实现第二步&#xff1a;提取共性并实现策略接口第三步&#xff1a;实现具体策略类第四步&#xff1a;实现上下文类策略模式 UML 图策略模式的 UML 图解析 例二&#xff1a;逐步重构…

主成分分析SPSS步骤+Matlab程序

SPSS 导入数据 主成分分析 参数设置 选择要压缩的变量 输出结果 越陡说明信息差越大&#xff0c;反之信息差越小 导出数据 双击可以复制 粘贴到matlab 计算 Matlab clc,clear data readmatrix(例2.xlsx); %将数据保存在txt文件中 data zscore(data); %数据的标准化 …

使用java加载、调用onnx模型(二)

目录 1、摘要 2、实现过程 2.1、依赖 2.2、imread 2.3、contiguous函数 2.3.1、转化示例 2.3.3、核心代码 2.4、Flatten拉直 2.5、最终结果 3、完整代码 1、摘要 在上一篇文章中 使用java加载、调用onnx模型_onnx java-CSDN博客 发现使用Java加载调用模型的分类结…

计算组合数:从n个不同元素中,选k个元素的方式数量math.comb()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 计算组合数&#xff1a; 从n个不同元素中&#xff0c; 选k个元素的方式数量 math.comb() 请问关于以下代码表述正确的选项是&#xff1f; import math print("【执行】math.comb(3, 2)…

线性代数证明:把行列式的某一行(列)的k倍加到另一行(列),行列式的值不变

线性代数证明 把行列式的某一行&#xff08;列&#xff09;的k倍加到另一行&#xff08;列&#xff09;&#xff0c;行列式的值不变&#xff1a; 注意五角星的位置要用到另一条性质&#xff1a;若行列式的某一行&#xff08;列&#xff09;的元素都是两数之和&#xff0c;则可以…

Ajax笔记总结(Xmind格式):第一天

Xmind鸟瞰图&#xff1a; 简单文字总结&#xff1a; ajax知识总结&#xff1a; 网络的参考模型&#xff1a; 1.物理层&#xff1a;源设备到目的设备 底层传输就是比特流 2.数据链路层 进行电信号的处理 进行数据的分组 3.网路层 进行数据包的传递 进行不同网络的…

菱形继承和虚继承

菱形继承&#xff08;Diamond Inheritance&#xff09;是指在多重继承的情况下&#xff0c;某个类继承自两个类&#xff0c;而这两个类又都继承自同一个基类的情况。 在这个结构中&#xff0c;D 直接从 A 继承了 A 的所有特性&#xff0c;但通过 B 和 C 继承&#xff0c;这会导…

Avue实现动态查询与数据展示(附Demo)

目录 前言1. 基本知识2. Demo 前言 此框架为Avue-crud&#xff0c;推荐阅读&#xff1a; 【vue】avue-crud表单属性配置&#xff08;表格以及列&#xff09;Avue实现批量删除等功能&#xff08;附Demo&#xff09;Avue实现选择下拉框的多种方式Avue框架实现图表的基本知识 | …

凌晨突发!核心系统瘫痪,通过Signleton单例模式轻松搞定,但还是被裁员了...

&#x1f345; 作者简介&#xff1a;哪吒&#xff0c;CSDN2021博客之星亚军&#x1f3c6;、新星计划导师✌、博客专家&#x1f4aa; &#x1f345; 哪吒多年工作总结&#xff1a;Java学习路线总结&#xff0c;搬砖工逆袭Java架构师 &#x1f345; 技术交流&#xff1a;定期更新…

selenium底层原理详解

目录 1、selenium版本的演变 1.1、Selenium 1.x&#xff08;Selenium RC时代&#xff09; 1.2、Selenium 2.x&#xff08;WebDriver整合时代&#xff09; 1.3、Selenium 3.x 2、selenium原理说明 3、源码说明 3.1、启动webdriver服务建立连接 3.2、发送操作 1、seleni…

flink车联网项目:维表离线同步(第69天)

系列文章目录 3.3 维表离线同步 3.3.1 思路 3.3.2 示例 3.3.3 其他表开发 3.3.4 部署 3.3.1.1 将表提交到生成环境 3.3.1.2 添加虚拟节点 3.3.1.3 配置计算节点 3.3.1.4 添加虚拟结束节点 3.3.1.5 提交到生产环境 3.3.1.6 发布 3.3.1.7 运维中心 3.3.1.8 补数据 3.3.1.9 补数据…

c++进阶------多态

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

机器学习/数据分析--通俗语言带你入门线性回归(结合案例)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 机器学习是深度学习和数据分析的基础&#xff0c;接下来将更新常见的机器学习算法注意&#xff1a;在打数学建模比赛中&#xff0c;机器学习用的也很多&a…

探索GitLab:从搭建到高效使用的实用指南

企业里为什么喜欢使用GitLab 一、GitLab简介二、搭建GitLab三、GitLab的权限管理3.1、用户注册3.2、创建用户组3.3、为用户组添加用户3.4、为工程添加访问权限 四、GitLab的code review五、团队知识管理六、总结 一、GitLab简介 GitLab是利用 Ruby on Rails 一个开源的版本管理…

Adobe Media Encoder ME 2023-23.6.6.2 解锁版下载安装教程 (专业的视频和音频编码渲染工具)

前言 Adobe Media Encoder&#xff08;简称Me&#xff09;是一款专业的音视频格式转码软件&#xff0c;文件格式转换软件。主要用来对音频和视频文件进行编码转换&#xff0c;支持格式非常多&#xff0c;使用系统预设设置&#xff0c;能更好的导出与相关设备兼容的文件。 一、…

网站怎么做敏感词过滤,敏感词过滤的思路和实践

敏感词过滤是一种在网站、应用程序或平台中实现内容审查的技术&#xff0c;用于阻止用户发布包含不适当、非法或不符合政策的内容。我们在实际的网站运营过程中&#xff0c;往往需要担心某些用户发布的内容中包含敏感词汇&#xff0c;这些词汇往往会导致我们的网站被用户举报&a…

JVM的组成

JVM 运行在操作系统之上 java二进制字节码文件的运行环境 JVM的组成部分 java代码在编写完成后编译成字节码文件通过类加载器 来到运行数据区,主要作用是加载字节码到内存 包含 方法区/元空间 堆 程序计数器,虚拟机栈,本地方法栈等等 随后来到执行引擎,主要作用是翻译字…

系统工程与信息系统(上)

系统工程 概念 【系统工程】是一种组织管理技术。 【系统工程】是为了最好的实现系统的目的&#xff0c;对系统的组成要素、组织结构、信息流、控制机构进行分析研究的科学方法。 【系统工程】从整体出发、从系统观念出发&#xff0c;以求【整体最优】 【系统工程】利用计算机…

信息搜集--敏感文件Banner

免责声明:本文仅做分享参考... git安装: Windows10下安装Git_win10安装git好慢-CSDN博客 git目录结构: Git 仓库目录 .git 详解-CSDN博客 敏感目录泄露 1-git泄露 Git是一个开源的分布式版本控制系统,我们简单的理解为Git 是一个*内容寻址文件系统*&#xff0c;也就是说Gi…

二十四、解释器模式

文章目录 1 基本介绍2 案例2.1 Instruction 接口2.2 StartInstruction 类2.3 PrimitiveInstruction 类2.4 RepeatInstruction 类2.5 InstructionList 类2.6 Context 类2.7 Client 类2.8 Client 类的运行结果2.9 总结 3 各角色之间的关系3.1 角色3.1.1 AbstractExpression ( 抽象…