【LeetCode363】矩形区域不超过 K 的最大数值和(前缀和+二分)

2023-10-26

 

如果暴力枚举的话,确定矩形区域需要两个顶点,时间复杂度就是O(m^{2}n^{2}),m和n最大100,计算量最大为10^{8},容易超时。 

 

 确定一个矩形区域一定要四条边,但我们要确定一个矩形区域是想求出它的和以满足最大的不超过k。而矩形区域的和可以看成是一列一列的和,如果我们把每一列的和全部求出来,实际上矩形区域的和就是一个数组的和。

 

我们可以只用枚举三条边,而第四条边可以采用二分查找,减少第四条边的枚举。

对于一维数组,想要知道区间内的和可以使用前缀和,也就是数组第i项的值为前i项的和 ,其实在求和的过程中就确定了第三条边。

for (int i = 0; i < m; ++i) { // 枚举上边界
            for (int j = i; j < m; ++j) { // 枚举下边界
                for (int c = 0; c < n; ++c) {
                    sum[c] += matrix[j][c]; // 更新每列的元素和
                }
                
            }
        }

既然第四条边需要使用到二分查找,我们可以用set里的lower_bound来求。 假定第四条边对应着前i项的值,第三条边对应着前j项的值,我们就是要找出满足S_{j}-S_{i}<=k的最大S_{j}-S_{i},变一下式子,就是要找出满足S_{i}>=S_{j}-k的最小S_{i},这个S_{i}可以用set来维护。

auto lb = sumSet.lower_bound(s - k);
if (lb != sumSet.end()) {
    ans = max(ans, s - *lb);
}
sumSet.insert(s);

完整代码C++ 

class Solution {
public:
    int maxSumSubmatrix(vector<vector<int>> &matrix, int k) {
        int ans = INT_MIN;
        int m = matrix.size(), n = matrix[0].size();
        for (int i = 0; i < m; ++i) { // 枚举上边界
            vector<int> sum(n);
            for (int j = i; j < m; ++j) { // 枚举下边界
                for (int c = 0; c < n; ++c) {
                    sum[c] += matrix[j][c]; // 更新每列的元素和
                }
                set<int> sumSet{0};
                int s = 0;
                for (int v : sum) {
                    s += v;
                    auto lb = sumSet.lower_bound(s - k);
                    if (lb != sumSet.end()) {
                        ans = max(ans, s - *lb);
                    }
                    sumSet.insert(s);
                }
            }
        }
        return ans;
    }
};

补充关于set的用法。

insert()//插入元素
count()//判断容器中是否存在某个元素
size()//返回容器的尺寸,也可以元素的个数
erase()//删除集合中某个元素
clear()//清空集合
empty()//判断是否为空
begin()//返回第一个节点的迭代器
end()//返回最后一个节点加1的迭代器
rbegin()//反向迭代器
rend()//反向迭代器
find()//查找某个指定元素的迭代器
lower_bound()//二分查找第一个不小于某个值的元素的迭代器
get_allocator()//返回集合的分配器
swap()//交换两个集合的变量
max_size()//返回集合能容纳元素的最大限值

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【LeetCode363】矩形区域不超过 K 的最大数值和(前缀和+二分) 的相关文章

  • 区块链原理与应用(一)

    1 什么是区块链 mermaid svg z62l3eavYilXMK3m label font family trebuchet ms verdana arial font family var mermaid font family f
  • 【ML】2023 年面向初学者的十大机器学习项目

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore

随机推荐

  • elementUI 的 table 表格改变数据不更新问题

    预期效果 点击输入框旁边的图标 输入框变为可输入状态 这里控制输入的 editable 字段不是 data 原有的属性 也不是 data 赋值时就存在的字段 问题原因 在 Vue 实例创建时 以及 data 赋值时 editable 并未声
  • 随机从数组或集合中抽取一个值或 从list集合中随机抽几个值 或算权重

    直接上代码 package cn itcast jk util import java util Arrays import java util HashSet import java util Map import java util S
  • Xilinx-FPGA关于BUFFER(时钟/普通IO信号)的使用总结

    目录 前言 一 时钟BUFFER使用总结 二 普通IO输出时钟信号时的推荐方法 使用ODDR 前言 Xilinx FPGA开发过程中 关于时钟信号和普通IO信号引入FPGA内部需要遵循一定的使用方法 现在自己一年多使用过的内容做一个总结 也
  • springmvc request与response获取

    request与response是Tomcat服务器在收到客户端请求后自己生成的 无需我们自己创建 但是在使用的时候可以有以下三种方式去获取 1 Controller直接使用 方法上直接使用 通过DispatcherServlet将参数传到
  • linux 查看当前系统时间,并实时刷新

    使用watch命令 周期性的执行一个命令 并全屏显示 watch n 1 date即可 每1秒刷新date命令 格式 watch option command watch n 1 date n interval 表示每n秒执行date n最
  • nodejs中使用数据库逆向映射字段

    安装依赖 在搭建项目时 一般都是先创建数据库 在使用服务去访问数据 但是由于数据库的映射非常麻烦 导致需要书写大量的映射文件 对于nodejs 这里提出一个逆向工程 本文使用的是mysql数据库 首先安装 npm init 先初始化项目 n
  • java实现具有修饰的完美圣诞树

    A 有咋样的实力可以写出这个代码 B 会for循环就好 A 只要会for就好 B 还有一点点逻辑能力和算法 package 海绵hong import java util Scanner public class text9 public
  • Linux下errno所代表的含义

    errno记录系统的最后一次错误代码 是一个int型 在errno h中定义 以下程序用于输出errno所代表的含义 0 133有意义 其余的属于未定义 include
  • 向ftp上传文件失败的可能原因

    1 文件编码问题引起 现象 上传含有中文符号的文件会上传失败 解决方法 将文件名中的中文符号修改为英文符号即可上传成功 如果上传的文件名中没有中文符号也失败 可以试试将文件名修改为短一点的 如 11 待上传成功后再修改文件名称 2 ftp服
  • 油猴脚本编写教程

    油猴脚本 Tampermonkey 是一个非常流行的浏览器扩展 它可以运行由广大社区编写的扩展脚本 来实现各式各样的功能 常见的去广告 修改样式文件 甚至是下载视频 今天我们就来看看如何编写自己的油猴脚本 当然为了运行油猴脚本 你应该在浏览
  • 在web项目启动时,执行某个方法

    在web项目启动时 执行某个方法 在web项目中有很多时候需要在项目启动时就执行一些方法 而且只需要执行一次 比如 加载解析自定义的配置文件 初始化数据库信息等等 在项目启动时就直接执行一些方法 可以减少很多繁琐的操作 在工作中遇到了项目初
  • 【计算机网络】物理层:数据通信系统模型

    一个数据通信系统可划分三大部分 发送方 源系统 发送端 传输系统 传输网络 接受方 接受端 目的系统 发送方包括 源点 源点设备产生要传输的数据 发送器 源点生成的数字比特流要通过发送器编码后才能够在传输系统中传输 典型的发送器是调制器 接
  • 文档在线预览解决方案——openoffice转换

    文档在线预览是一个复杂功能 文档格式的繁复更加增加了难度 虽然office给出了在线预览功能 https products office com en us office online view office documents onlin
  • C++基础——运算符重载函数讲解与练习

    目录 前言 一 运算符重载 1 定义 2 函数名字为 3 函数原型 练习 对比两个日期类对象是否相等 函数重载 练习 对比两个日期类对象 gt gt 的运算符重载函数 对于小于 小于等于 不等于的函数重载如下 练习 日期类对象 天数的重载函
  • 图像的读取,显示与保存(基于skimage模块)

    一 skiamge模块 skimage包的全称是scikit image SciKit toolkit for SciPy 它对scipy ndimage进行了扩展 提供了更多的图片处理功能 它是由python语言编写的 由scipy 社区
  • drone的简单使用

    一 简介 Drone 是一个基于Docker容器技术的可扩展的持续集成引擎 用于自动化测试 构建 发布 每个构建都在一个临时的Docker容器中执行 使开发人员能够完全控制其构建环境并保证隔离 开发者只需在项目中包含 drone yml文件
  • 强化学习之有模型学习

    在前面一篇简单介绍了强化学习的概念和模型 具体介绍了K 摇臂赌博机的原理并对比不同模型不同参数下的运行效果 可以参考前面一篇链接 强化学习之k 摇臂赌博机 易 的博客 CSDN博客 本次介绍有模型学习 有模型学习指的是马尔可夫决策过程的四元
  • Inside Real-Time Linux

    本文转载于 https www linux com news event elce 2017 2 inside real time linux Real time Linux has come a long way in the past
  • stm32通用定时器用做外部脉冲计数器的例程

    原文 https blog csdn net sdutkqb article details 39100971 最近几天要用到stm32对外部输入脉冲进行计数 很自然想到定时器 可是手上资料没有讲解stm32定时器如何用作外部计数器的 在网
  • 【LeetCode363】矩形区域不超过 K 的最大数值和(前缀和+二分)

    如果暴力枚举的话 确定矩形区域需要两个顶点 时间复杂度就是 m和n最大100 计算量最大为 容易超时 确定一个矩形区域一定要四条边 但我们要确定一个矩形区域是想求出它的和以满足最大的不超过k 而矩形区域的和可以看成是一列一列的和 如果我们把