lc1074.元素和为目标值的子矩阵数量

这篇具有很好参考价值的文章主要介绍了lc1074.元素和为目标值的子矩阵数量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

lc1074.元素和为目标值的子矩阵数量,矩阵,算法,线性代数创建二维前缀和数组

两个for循环,外循环表示子矩阵的左上角(x1,y1),内循环表示子矩阵的右下角(x2,y2)

两个for循环遍历,计算子矩阵的元素总和

四个变量,暴力破解的时间复杂度为O(m^2*n^2)(m、n为matrix数组的行数和列数)

优化

计算每一行的前缀和,而不是整个矩阵的前缀和。

取不同的两个列(j1,j2),计算以这两个列为边界计算每一行的前缀和(这就是二维前缀和)

这样就可以减少一个变量遍历,时间复杂度为O(m^2*n)(m、n为matrix数组的行数和列数)

代码文章来源地址https://www.toymoban.com/news/detail-633445.html

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

public class SubmatrixNumber {
    @Test
    public void test() {
        int[][] matrix = new int[][]{{0, 1, 0}, {1, 1, 1}, {0, 1, 0}};
//        for (int[] arr:getPrefixAnd(matrix)) {
//            for (int i:arr) {
//                System.out.print(i+" ");
//            }
//            System.out.println();
//        }
        System.out.println(submatrixNumber(matrix, 0));//4
        int[][] matrix1 = new int[][]{{1, -1}, {-1, 1}};
        System.out.println(submatrixNumber(matrix1, 0));//5
        int[][] matrix2 = new int[][]{{904}};
        System.out.println(submatrixNumber(matrix2, 0));//0
    }

    public static int submatrixNumber(int[][] matrix, int target) {
        int[][] sum = getPrefixAnd1(matrix);
        int ans = 0;
        Map<Integer, Integer> count = new HashMap<>();//负责记录计算出的每两列之间的前缀和出现的次数

        int endY = 1;
        while (endY <= matrix[0].length) {
            for (int startY = 0; startY < endY; startY++) {//两个列的边界
                int prefixAnd = 0;
                count.clear();//两个列的边界不同,此时计算出的前缀和不同,负责记录的map集合需要初始化
                count.put(0, 1);//当矩阵为空时,需要记录0出现了1次

                for (int k = 1; k <= matrix.length; k++) {//遍历行
                    prefixAnd += (sum[k][endY] - sum[k][startY]);//计算以这两个列为边界计算每一行的前缀和
                    if (count.containsKey(prefixAnd - target)) {//count集合中是否存在key值为temp-target的数,即为temp-target这个数是否是第一次出现
                        ans += count.get(prefixAnd - target);//不是第一次,则取value值加上
                    }
                    count.put(prefixAnd, count.getOrDefault(prefixAnd, 0) + 1);//记录次数加一
                    //defaultValue - 当指定的key并不存在映射关系中,则返回的该默认值
                    //即如果是第一次出现,则默认的次数记为0
                }
            }
            endY++;
        }
        return ans;
    }




    public static int[][] getPrefixAnd(int[][] matrix) {
        int[][] sum = new int[matrix.length][matrix[0].length];

        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (i == 0 && j > 0) {//第一行
                    sum[i][j] = sum[i][j - 1] + matrix[i][j];
                } else if (j == 0 && i > 0) {
                    sum[i][j] = sum[i - 1][j] + matrix[i][j];
                } else if (i == 0 && j == 0) {
                    sum[0][0] = matrix[0][0];
                } else {
                    sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + matrix[i][j];
                }
            }
        }
        return sum;

    }


    //sum[0][0] == 0
    public static int[][] getPrefixAnd1(int[][] matrix) {
        int[][] sum = new int[matrix.length+1][matrix[0].length+1];
        for (int i = 1; i <= matrix.length; i++) {
            for (int j = 1; j <= matrix[0].length; j++) {
                sum[i][j] = sum[i][j - 1] + matrix[i - 1][j - 1];
            }
        }
        return sum;
    }
}



到了这里,关于lc1074.元素和为目标值的子矩阵数量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 每日一题:LeetCode-LCR 179. 查找总价格为目标值的两个商品

    前言: 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈    🔎🔎如果说代码有灵魂,那么它的灵魂一定是👉👉 算法 👈👈,因此,想要写出💚优美的程序💚,核心算法是必不可少的,少年,你渴望力量吗😆😆,想掌握程序的灵魂吗❓❗️那么就必须踏上这样一条漫长

    2024年02月03日
    浏览(41)
  • [双指针] (三) LeetCode LCR 179. 查找总价格为目标值的两个商品 和 15. 三数之和

    [双指针] (三) LeetCode LCR 179. 查找总价格为目标值的两个商品 和 15. 三数之和 查找总价格为目标值的两个商品 LCR 179. 查找总价格为目标值的两个商品 题目分析 (1) 数组内数字是升序 (2) 目标值为target (3) 找两数之和为target 解题思路 找两个数字的和与目标值相等,我们可以想到

    2024年02月05日
    浏览(33)
  • [Algorithm][前缀和][和为K的子数组][和可被K整除的子数组][连续数组][矩阵区域和]详细讲解

    和为 K 的子数组 分析 :因为有 负数 的存在 无法使用\\\" 双指针 \\\"优化,因为 区间求和不具备单调性 可能已经找到前缀和为k的子数组了,但是后面仍然可能会有更长的和为k的子数组存在 思路 :前缀和 + 哈希表 前缀和 : 以 i 位置为结尾 的所有的子数组 将问题转化为 :在

    2024年04月28日
    浏览(25)
  • 算法——前缀和之除自身以外数组的乘积、和为K的子数组、和可被K整除的子数组、连续数组、矩阵区域和

    这几道题对于我们前面讲过的一维、二维前缀和进行了运用,包含了面对特殊情况的反操作 目录 4.除自身以外数组的乘积 4.1解析 4.2题解 5.和为K的子数组 5.1解析 5.2题解 6.和可被K整除的子数组 6.1解析 6.2题解 7.连续数组 7.1题解 7.2题解 8.矩阵区域和 8.1解析 8.2题解 4.除自身以外

    2024年04月14日
    浏览(31)
  • 【每日一题Day292】LC1572矩阵对角线元素的和 模拟

    思路 简单模拟,主对角线的元素横纵坐标相等,副对角线的元素横纵坐标相加为n-1,注意避免重复计算 实现 复杂度 时间复杂度: O ( log ⁡ n ) mathcal{O}(log n) O ( lo g n ) 空间复杂度: O ( 1 ) mathcal{O}(1) O ( 1 )

    2024年02月13日
    浏览(28)
  • [Kadane算法,前缀和思想]元素和最大的子矩阵

    题目描述 输入一个n级方阵,请找到此矩阵的一个子矩阵,此子矩阵的各个元素的和是所有子矩阵中最大的,输出这个子矩阵及这个最大的和。 关于输入 首先输入方阵的级数n, 然后输入方阵中各个元素。 关于输出 输出子矩阵, 最后一行输出这个子矩阵的元素的和。 例子输

    2024年02月03日
    浏览(28)
  • 和为 K 的子数组——前缀和+哈希

    题目链接:力扣 注意:此题不能使用滑动窗口,因为数组中可能会出现负数。也就是说右指针向后移1位不能保证区间会增大,左指针向后移1位也不能保证区间和会减小。给定左右指针的位置没有二段性 已知sum[i]是从nums[0~i]的和,sum[i-1]是nums[0~i-1]的和 则有 sum[i] - sum[i-1] =

    2024年02月16日
    浏览(32)
  • 560. 和为 K 的子数组【哈希、前缀和】

    560. 和为 K 的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。 示例 1: 输入:nums = [1,1,1], k = 2 输出:2 示例 2: 输入:nums = [1,2,3], k = 3 输出:2 提示: 1 = nums.length = 2 * 104 -1000 = nums[i] = 1000 -107 = k = 107 C代码:哈希、前缀和

    2024年02月02日
    浏览(34)
  • hot100:10和为k的子数组

    题目链接: LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台 算法思想: 法一(暴力法): 使用两层for循环列举出所有的子数组,使用一个变量sum求得子数组的和并判断是否为k 法二(前缀和+哈希表): 前缀和:前缀和就是从下标为0的元素开始到当

    2024年01月23日
    浏览(35)
  • 【LeetCode热题100】【子串】和为 K 的子数组

    题目 给你一个整数数组  nums  和一个整数  k  ,请你统计并返回  该数组中和为  k   的子数组的个数  。 子数组是数组中元素的连续非空序列。 示例 1: 示例 2: 提示: 1 = nums.length = 2 * 104 -1000 = nums[i] = 1000 -107 = k = 107 暴力  直接两层循环找出所有连续子数组的和,这个

    2024年01月19日
    浏览(26)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包