《剑指 Offer》专项突破版 - 面试题 13 : 二维子矩阵的数字之和(C++ 实现)- 二维前缀和

这篇具有很好参考价值的文章主要介绍了《剑指 Offer》专项突破版 - 面试题 13 : 二维子矩阵的数字之和(C++ 实现)- 二维前缀和。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目链接:LCR 013. 二维区域和检索 - 矩阵不可变 - 力扣(LeetCode)

题目

输入一个二维矩阵,如何计算给定左上角坐标和右下角坐标的子矩阵的数字之和?对于同一个二维矩阵,计算子矩阵的数字之和的函数可能由于输入不同的坐标而反复调用多次。

例如,对于下图中的二维矩阵,输入左上角坐标 (2, 1) 和右下角坐标 (4, 3),该函数输出 8(红色框的子矩阵的数字之和);输入左上角坐标 (1, 1) 和右下角坐标 (2, 2),该函数输出 11(绿色框的子矩阵的数字之和);输入左上角坐标 (1, 2) 和右下角坐标 (2, 4),该函数输出 12(蓝色框的子矩阵的数字之和)。

《剑指 Offer》专项突破版 - 面试题 13 : 二维子矩阵的数字之和(C++ 实现)- 二维前缀和,数据结构,矩阵,c++,线性代数,数据结构,算法,leetcode,面试

分析

如果不考虑时间复杂度,则采用蛮力法用两个嵌套的循环总是可以求出一个二维矩阵的数字之和。如果矩阵的行数和列数分别是 m 和 n,那么这种蛮力法的时间复杂度是 O(mn)。

只是这个题目提到,对于一个二维矩阵,可能由于输入不同的坐标而反复求不同子矩阵的数字之和,这说明应该优化求和的过程,要尽可能快地实现子矩阵的数字求和。

如果仔细分析子矩阵的数字之和的规律,就可以发现左上角坐标为 (r1, c1)、右下角坐标为 (r2, c2) 的子矩阵的数字之和可以用 4 个左上角坐标为 (0, 0) 的子矩阵的数字之和求得。下图中的阴影部分表示左上角坐标为 (r1, c1)、右下角坐标为 (r2, c2) 的子矩阵。该矩阵的数字之和等于左上角坐标为 (0, 0)、右下角坐标为 (r2, c2) 的子矩阵的数字之和减去左上角坐标为 (0, 0)、右下角坐标为 (r1 - 1, c2) 的子矩阵的数字之和,再减去左上角坐标为 (0, 0)、右下角坐标为 (r2, c1 - 1) 的子矩阵的数字之和,最后加上左上角坐标为 (0, 0)、右下角坐标为 (r1 - 1, c1 - 1) 的子矩阵的数字之和

《剑指 Offer》专项突破版 - 面试题 13 : 二维子矩阵的数字之和(C++ 实现)- 二维前缀和,数据结构,矩阵,c++,线性代数,数据结构,算法,leetcode,面试

因此,可以在预处理阶段求出从左上角坐标为 (0, 0) 到每个右下角坐标的子矩阵的数字之和。首先创建一个和输入矩阵大小相同的辅助矩阵 sums,该矩阵中的坐标 (i, j) 的数值为输入矩阵中从左上角坐标 (0, 0) 到右下角坐标 (i, i) 的子矩阵的数字之和

有了这个辅助矩阵 sums,再求左上角坐标为 (r1, c1)、右下角坐标为 (r2, c2) 的子矩阵的数字之和就变得比较容易。该子矩阵的数字之和等于 sums[r2][c2] - sums[r1 - 1][c2] - sums[r2][c1 - 1] + sums[r1 - 1][c1 - 1]

下面分析如何生成辅助矩阵 sums,即求得数组中的每个数字 sums[i][j]。按照生成辅助矩阵 sums 的规则,sums[i][j] 的值等于输入矩阵中从左上角坐标为 (0, 0) 到右下角坐标为 (i, j) 的子矩阵的数字之和。可以把左上角坐标为 (0, 0) 到右下角坐标为 (i, j) 的子矩阵的数字看成由两部分组成。第 1 部分是从左上角坐标为 (0, 0) 到右下角坐标为 (i - 1, j) 的子矩阵,该子矩阵的数字之和等于 sums[i - 1][j]。第 2 部分是输入矩阵中第 i 行中列号从 0 到 j 的所有数字,如果按照从左到右的顺序计算 sums[i][j],则可以逐个累加第 i 行的数字,从而得到子矩阵第 2 部分的数字之和

class NumMatrix {
private:
    vector<vector<int>> sums;
public:
    NumMatrix(vector<vector<int>>& matrix) {
        int m = matrix.size();
        int n = matrix[0].size();
        sums.resize(m + 1, vector<int>(n + 1, 0));
        for (int i = 0; i < m; ++i)
        {
            int rowSum = 0;
            for (int j = 0; j < n; ++j)
            {
                rowSum += matrix[i][j];
                sums[i + 1][j + 1] = sums[i][j + 1] + rowSum;
            }
        }
    }
    
    int sumRegion(int row1, int col1, int row2, int col2) {
        return sums[row2 + 1][col2 + 1] - sums[row1][col2 + 1] - sums[row2 + 1][col1] + sums[row1][col1];
    }
};

注意:如果输入的行数和列数分别是 m 和 n,那么辅助数组 sums 的行数和列数分别为 m + 1 和 n + 1,这样只是为了简化代码逻辑。如果用公式 sums[r2][c2] - sums[r1 - 1][c2] - sums[r2][c1 - 1] + sums[r1 - 1][c1 - 1] 求解左上角坐标为 (r1, c1)、右下角坐标为 (r2, c2) 的子矩阵的数字之和,由于坐标值 r1 或 c1 有可能等于 0,因此 r1 - 1 或 c1 - 1 可能是负数,不再是有效数组的下标。如果在矩阵的最上面增加一行,最左面增加一列,这样就不必担心出现数组下标为 -1 的情形文章来源地址https://www.toymoban.com/news/detail-802455.html

到了这里,关于《剑指 Offer》专项突破版 - 面试题 13 : 二维子矩阵的数字之和(C++ 实现)- 二维前缀和的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《剑指offer》 图专项突破

    题目 海洋岛屿地图可以用由 0 、 1 组成的二维数组表示,水平或者竖直方向相连的一组 1 表示一个岛屿。请计算最大的岛屿的面积(即岛屿中 1 的数目)。例如,在图15.5中有 4 个岛屿,其中最大的岛屿的面积为 5 。 图15.5:用 0 、 1 矩阵表示的海洋岛屿地图。地图中有 4 个岛

    2024年01月16日
    浏览(63)
  • 《剑指offer》专项突破

    题目 输入两个 int 型整数,求它们除法的商,要求不得使用乘号’ * ‘、除号’ / ‘以及求余符号’ % \\\'。当发生溢出时返回最大的整数值。假设除数不为 0 。例如,输入 15 和 2 ,输出 15/2 的结果,即 7 。 参考代码 题目 输入两个表示 二进制 的字符串,请计算它们的和,并以

    2024年02月01日
    浏览(56)
  • 剑指offer面试题8 旋转数组的最小数字

    分析 首先一定要记住只要看到排序数组的查找,思维一定要往二分法上靠,然后再思考清楚如何利用二分法。而如何利用二分法一定要仔细分析所给的数组的特点:递增数组且最开始的若干元素搬到数组的末尾,相当于该数组由俩个递增小数组构成,前面的数组元素肯定大于

    2024年01月24日
    浏览(39)
  • (数组与矩阵) 剑指 Offer 03. 数组中重复的数字 ——【Leetcode每日一题】

    难度:简单 找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 示例 1: 输入 : [2, 3, 1, 0, 2, 5, 3] 输出 :2 或

    2024年02月16日
    浏览(39)
  • 剑指offer12 矩阵中的路径 13 机器人的运动范围 34.二叉树中和为某一值得路径

    //写的有点问题,暂时想不到怎么改,先放着,通过用例71/83 卡住的是abcd 但是改了又有问题 无语 看了 答案 都写不对 在类成员里面定义了row和col 就不要重复定义了 不然不知道为什么就开始发疯 先贴出蠢货写出来的东西 审题也审不明白 机器人只能上下左右走 不能一行一行

    2024年02月15日
    浏览(38)
  • 剑指29.顺时针打印矩阵 31 栈的压入,弹出序列 03 数组中的重复数字 53缺失的数字 04二维数组中的查找

    回字形 思路:pushed数组里遍历进栈,遍历时候,先进栈,再判断栈顶是否和poped序列的当前指向的是否一样,一样就pop,直到不一样为止,然后继续遍历进栈。然后再判断栈里面剩余的和poped序列指向的一不一样,一样,就把栈里面的pop,直到栈为空,只要有一个不一样,就

    2024年02月16日
    浏览(41)
  • 剑指offer -- 二维数组中的查找

    二维数组中的查找_牛客题霸_牛客网 (nowcoder.com) 暴力查找法: 是一种简单直接的解决方法,可以用于在二维数组中查找目标值。该方法的思路是遍历数组的每个元素,逐个与目标值进行比较。 具体步骤如下: 从数组的第一行第一列开始,逐行逐列地遍历数组的每个元素。 对

    2024年02月06日
    浏览(90)
  • 剑指offer中算法:二维数组中的查找

    在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 示例 现有矩阵 matrix 如下: { {1, 4, 7}, {2, 5, 8,}, {3, 6, 9} } 给定 target = 9,

    2024年02月12日
    浏览(43)
  • 从零学算法 (剑指 Offer 13)

    地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+

    2024年02月11日
    浏览(33)
  • 【剑指offer|图解|数组】寻找文件副本 + 螺旋遍历二维数组

    🌈个人主页: 聆风吟 🔥系列专栏: 数据结构、剑指offer每日一练 🔖少年有梦不应止于心动,更要付诸行动。 ⌈ 在线OJ链接,可以转至此处自行练习 ⌋ 设备中存有 n 个文件,文件 id 记于数组 documents 。若文件 id 相同,则定义为该文件存在副本。请返回任一存在副本的文件

    2024年02月05日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包