[c++]力扣303+304 区域和检索 二维区域和检索

2023-11-15

最近开始重新刷题,从链表开始。第一部分是前缀和。分为一维数组前缀和和高维数组前缀和。(abandon…)

前缀和数组是牺牲空间换时间的方法,为了解决频繁访问数组某区间的问题,先构造出从开始到当前位置的元素的和,储存在前缀和数组中。查询的时候直接查询前缀和数组,就能把时间复杂度降到O(1)。

大概就是在调用构造函数的时候就额外构造一个这么个数组,查的时候直接从前缀和数组中返回值。这里因为数组是直接内存访问,所以快!

力扣303和304两个题都是前缀和数组可以解的题。

303 区域和检索 - 数组不可变

原题链接
题目原文:
给定一个整数数组nums,处理以下类型的多个查询:

  1. 计算索引leftright(包含leftright)之间的nums元素的和,其中left<=right

实现NumArray类:

  • NumArray(int[] nums)使用数组nums初始化对象
  • int sumRange(int i, int j)返回数组nums中索引leftright之间的元素的总和,包含leftright两点

|ू・ω・` )
一维数组的前缀和无可厚非,下标对应起来:
preSum[i] = nums[0] + … + nums[i];
preSum[0] = nums[0];

class NumArray {
private:
    vector<int> preSum;
    vector<int> nums;
    int len;
public:
    NumArray(vector<int>& nums) {
        this->len = nums.size();
        this->nums = nums;
        this->preSum.resize(len + 1);
        preSum[0] = 0;

        for(int i = 1; i <= len; i++) preSum[i] = nums[i - 1] + preSum[i - 1];
    }
    
    int sumRange(int left, int right) {
        if(left < 0 || right >= len || left >= len) return -1;
        return this->preSum[right + 1] - preSum[left];
    }
};

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray* obj = new NumArray(nums);
 * int param_1 = obj->sumRange(left,right);
 */

304 二维区域和检索 - 矩阵不可变

一样的思路:
preSum[i][j] = nums[0][0] + … + nums[0][j] + … + nums[i][j];

简化计算:就是求相交的几个四边形面积的小学计算题:
preSum[i][j] = nums[i][j] + preSum[i - 1][j] + preSum[i][j - 1] - preSum[i - 1][j - 1];
边缘情况:
第一列:preSum[i][j] = nums[i][j] + preSum[i - 1][j];
第一行:preSum[i][j] = nums[i][j] + preSum[i][j - 1];

/*
 *  1  2
 *  3  4
 *
 * 和 = 4 + 1 - 2 - 3
*/
class NumMatrix {
private:
    vector<vector<int>> preSum;
    vector<vector<int>> matrix;
    int row; // 行数
    int col; // 列数
    void output(vector<vector<int>> &m) {
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) cout << m[i][j] << " ";
            cout << endl; 
        }
    }
public:
    NumMatrix(vector<vector<int>>& matrix) {
        this->matrix = matrix;
        this->row = matrix.size();
        this->col = matrix[0].size();
        this->preSum.resize(row);
        for(int i = 0; i < row; i++) preSum[i].resize(col);

        /*
        output(this->matrix);
        cout << endl;
        output(this->preSum);
        */

        // 和数组
        for(int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if(i == 0 && j == 0) preSum[i][j] = matrix[i][j];
                else if(i == 0 && j != 0) preSum[i][j] = matrix[i][j] + preSum[i][j - 1];
                else if(i != 0 && j == 0) preSum[i][j] = matrix[i][j] + preSum[i - 1][j];
                else if(i != 0 && j != 0) preSum[i][j] = matrix[i][j] + preSum[i - 1][j] + preSum[i][j - 1] - preSum[i - 1][j - 1];
            }
        } 
        /*
        cout << endl;
        output(this->preSum);
        */
    }
    
    int sumRegion(int row1, int col1, int row2, int col2) {
        if(row1 < 0 || row2 < 0 || col1 < 0 || col2 < 0 || row1 >= row || row2 >= row || col1 >= col || col2 >= col) return -1;
        if(row1 == 0 && col1 == 0) return preSum[row2][col2];
        else if(row1 == 0 && col1 != 0) return preSum[row2][col2] - preSum[row2][col1 - 1];
        else if(row1 != 0 && col1 == 0) return preSum[row2][col2] - preSum[row1 - 1][col2];
        else return preSum[row2][col2] + preSum[row1 - 1][col1 - 1] - preSum[row1 - 1][col2] - preSum[row2][col1 - 1];
    }
};

/**
 * Your NumMatrix object will be instantiated and called as such:
 * NumMatrix* obj = new NumMatrix(matrix);
 * int param_1 = obj->sumRegion(row1,col1,row2,col2);
 */
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[c++]力扣303+304 区域和检索 二维区域和检索 的相关文章

随机推荐

  • C语言 —— 合并两个有序数组

    C语言解决数组相关问题 合并有序数组 一 问题描述 二 解题思路 三 图文描述 四 代码展示 一 问题描述 给定两个有序整形数组arr1 和 arr2 将arr1 与 arr2合并或者有序输出成为一个有序数组 二 解题思路 1 给定的是两个
  • 16_Nginx_http请求处理的11个阶段

    文章目录 http 请求处理时的11个阶段 11个阶段的顺序处理 http 请求处理时的11个阶段 post read realip server rewrite rewrite find config rewrite rewrite po
  • 动力节点王鹤SpringBoot3笔记——第五章 说说Web服务

    目录 第五章 说说Web服务 5 1 高效构建Web应用 5 1 1 html页面视图 5 1 2 JSON视图 5 1 3 给项目加favicon 5 2 Spring MVC 5 2 1 控制器Controller 5 2 1 1 匹配
  • Oracle的大字段Clob类型的查询,Clob转为varchar展示

    1 Oracle中将clob字段数据转化为字符串 借鉴学习地址 Oracle的CLOB大数据字段类型 Grand Jon 博客园 查询 将CLOB转成字符类型 采用 dbms lob substr 查询 将CLOB转成字符类型 SELECT
  • 亚稳态学习小结

    亚稳态学习小结 一 亚稳态是什么 要知道亚稳态的定义 首先要知道时钟上升沿采样中的建立时间 setup time 和保持时间 hold time 1 1 建立时间 Tsu 保持时间 Th 建立时间 在触发器时钟上升沿到来之前 数据需要保持稳
  • xssgame靶场通关记录

    文章目录 靶场地址 第一关 第二关 第三关 第四关 第五关 第六关 第七关 第八关 html编码绕过 第九关 href属性js伪协议 第十关 第十一关 第十二关 第十三关 第十四关 Angular JS 第十五关 url编码 靶场地址 国光
  • UI设计原则背后的认知心理学 优漫动游

    了解人的感官和大脑是如何工作的 去衡量及判断那些设计原则更靠谱 UI设计师需要确定哪个设计原则更适用于给定的环境 从而优选应用 UI设计师必须深思熟虑 而不是盲目的应用设计原则 应该理解其基本原则并有过应用经验的人来使用和诠释 UI设计原则
  • vue3中使用echarts实现自定义纹理3d地图

    效果图 npm下载echarts 在main文件中全局引入 npm install echarts S import as Echarts from echarts app config globalProperties Echarts E
  • 使用htmlWebpackPlugin添加代码版本信息

    不知道你是不是这样的场景哈 或者曾经是 你提交完代码 部署然后测试去测 测试说你这个bug改了吗 怎么还是一样 然后你就纳闷 改过了啊代码也提交了 然后你自己去点一遍验证提交的代码有没有部署上去 这是一个痛点 可能也都习惯了哈 其实 这里有
  • OrCAD Capture学习笔记

    1 OrCAD Capture文件类型 OrCAD Capture是Cadence公司用来进行原理图绘制的一个EDA软件 能用这个软件打开的常用的几个文件后缀名为 dsn opj olb lib net 这些文件后缀具体表示的意思如下 这些
  • php 万能密码,网络安全系列之十 万能密码登录网站后台

    在登录网站后台时 有一个比较古老的 万能密码 漏洞 即利用一个我们精心构造的用户名 即使不用输入密码 也可以登录后台 其原理仍属于SQL注入的范畴 假设数据库中存放用户信息的表是admin 其中存放用户名的字段是username 存放密码的
  • git报错ssh: connect to host github.com port 22: Connection timed out

    碰到了git拉代码时报出的一个错误 通过查阅资料尝试了几种方法之后解决了 在这做个记录 首先需要检查一下SSH是否能够连接成功 输入以下命令 ssh T git github com 若还是报这个错ssh connect to host g
  • Solidity中的pure和view修饰符的区别是什么?什么时候添加pure和view修饰符?

    Solidity是一种用于编写智能合约的编程语言 它被广泛应用于以太坊区块链上的智能合约开发 在Solidity中 有两种函数修饰符 即 pure 和 view 它们被用来指示函数的行为 这篇文章将深入探讨 pure 和 view 的含义
  • PyTorch中使用预训练的模型初始化网络的一部分参数(增减网络层,修改某层参数等) 固定参数

    在预训练网络的基础上 修改部分层得到自己的网络 通常我们需要解决的问题包括 1 从预训练的模型加载参数 2 对新网络两部分设置不同的学习率 主要训练自己添加的层 一 加载参数的方法 加载参数可以参考apaszke推荐的做法 即删除与当前mo
  • 查看 elasticsearch版本号

    查看 elasticsearch版本号 输入命令 curl XGET localhost 9200 得到 name OmUcqLr cluster name elasticsearch cluster uuid AQHIcDW Q9K80U
  • 使用U盘重装MacBook Air时用到的工具和镜像

    主要是工具和镜像 非重装教程 前言 工具 镜像 前言 我之前没接触过苹果笔记本 设备是邻居的白苹果 近期因为双系统中的windows出故障了 所以索性帮他重装 用U盘重装MacBook Air教程网上有一堆 大家应该都能搜索到 主要是工具和
  • aanet

    AANet feature extractor AANetFeature conv1 Sequential 0 Conv2d 3 32 kernel size 7 7 stride 3 3 padding 3 3 bias False 1
  • VSCODE:终端界面简洁化和cmd.exe界面显示

    最近在配置vscode 想用来编写一些c和c 算法文件 编写helloword cpp文件 运行发现程序输出结果显示在终端界面 且含有一长串复杂的无用字符 因此考虑简化这个终端界面 在网上查询了众多教程 大部分都是修改launch json
  • 如何使用 Serverless 做架构和项目管理—— 三年全栈经验总结

    本文是从项目工程角度来讲解的 技术角度请参看另一个文章 真实项目代码教你四步扔了传统服务器 让你优雅使用Serverless做全栈开发 https zhuanlan zhihu com p 本文汇总了我的多个Serverless的全栈项目实
  • [c++]力扣303+304 区域和检索 二维区域和检索

    最近开始重新刷题 从链表开始 第一部分是前缀和 分为一维数组前缀和和高维数组前缀和 abandon 前缀和数组是牺牲空间换时间的方法 为了解决频繁访问数组某区间的问题 先构造出从开始到当前位置的元素的和 储存在前缀和数组中 查询的时候直接查