单调栈练习(四)— 统计全 1 子矩形

这篇具有很好参考价值的文章主要介绍了单调栈练习(四)— 统计全 1 子矩形。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目
同样的LeetCode原题:题目链接

给你一个 m x n 的二进制矩阵 mat ,请你返回有多少个 子矩形 的元素全部都是 1 。

单调栈练习(四)— 统计全 1 子矩形,算法,leetCode,算法,java,单调栈

单调栈
解题思路整体和上一篇文章差不多,都是用到了压缩数组的技巧,通过压缩数组来构建一个数组矩阵、以每一行为底, 每一列作为矩阵的高度,区别在于上一篇帖子是计算求矩阵的最大面积矩阵面积。而这道题是统计所有子矩阵个数。

所以这道题的区别在于,当遍历压缩数组时,以栈中弹出栈顶元素(cur)作为矩阵的高,并找到左右最近且小的值作为边界后。还要找到左右最近且小的值中的较大值(max)作为限制。只求 max ~ cur中的子矩阵的数量。

以下图为例,当前弹出的数组下标6的元素,高为6,左侧最近且小的值是在数组下标为3、高为3的值,右侧最近且小是在数组下标为9、高为4的值。
单调栈练习(四)— 统计全 1 子矩形,算法,leetCode,算法,java,单调栈
我们想求的是什么?
数组下标 4 ~ 8范围内。高度为5的子矩阵有多少, 高度为6的子矩阵有多少?也就是说,因为左右边界里,数组下标9的高度4 > 数组下标3的高度3。所以我们以4作为一个限制条件,只求范围内 > 4的子矩阵的个数。
其余 <= 4 那部分的子矩阵,等到下标9的元素弹出来时再算,这样算不会重复!!!
那4 ~ 8 范围内以5、6为高的子矩阵有多少?
一共有这些:(9 - 3) * (9 - 3 - 1) / 2 = 15
单调栈练习(四)— 统计全 1 子矩形,算法,leetCode,算法,java,单调栈
代码文章来源地址https://www.toymoban.com/news/detail-820621.html

public static int numSubmat(int[][] mat) {
        if (mat == null || mat[0].length == 0) {
            return 0;
        }

        int N = mat.length;
        int M = mat[0].length;
        int[] helpArr = new int[M];
        Integer sum = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                helpArr[j] = mat[i][j] == 0 ? 0 : helpArr[j] + 1;
            }
            sum += countFromBottom(helpArr);
        }
        return sum;
    }

    public static int countFromBottom(int[] height) {
        Stack<Integer> stack = new Stack<>();
        Integer sum = 0;

        for (int i = 0; i < height.length; i++) {
            while (!stack.isEmpty() && height[i] < height[stack.peek()]) {
                Integer cur = stack.pop();
                Integer leftMinIndex = stack.isEmpty() ? -1 : stack.peek();
                int n = i - leftMinIndex - 1;
                int max = Math.max(leftMinIndex == -1 ? 0 : height[leftMinIndex], height[i]);
                sum += (height[cur] - max) * num(n);
            }
            stack.push(i);
        }

        while (!stack.isEmpty()) {
            Integer cur = stack.pop();
            Integer leftMinIndex = stack.isEmpty() ? -1 : stack.peek();
            int n = height.length - leftMinIndex - 1;
            sum += (height[cur] - (leftMinIndex == -1 ? 0 : height[leftMinIndex])) * num(n);
        }
        return sum;
    }

    public static int num(int n) {
        return ((n * (1 + n)) >> 1);
    }

到了这里,关于单调栈练习(四)— 统计全 1 子矩形的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【leetcode:1944. 队列中可以看到的人数】单调栈算法及其相关问题

    1944. 队列中可以看到的人数 有  n  个人排成一个队列, 从左到右  编号为  0  到  n - 1  。给你以一个整数数组  heights  ,每个整数  互不相同 , heights[i]  表示第  i  个人的高度。 一个人能  看到  他右边另一个人的条件是这两人之间的所有人都比他们两人  矮  。更

    2024年01月25日
    浏览(34)
  • 算法leetcode|84. 柱状图中最大的矩形(rust重拳出击)

    给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 1 = heights.length =10 5 0 = heights[i] = 10 4 面对这道算法题目,二当家的再次陷入了沉思。 眼睛一看似乎有思路,但是一动手就容易不知

    2024年02月08日
    浏览(58)
  • 算法打卡day32|贪心算法篇06|Leetcode 738.单调递增的数字、968.监控二叉树

    Leetcode 738.单调递增的数字 题目链接:738.单调递增的数字  大佬视频讲解:单调递增的数字视频讲解  个人思路 这个题目就是从例子中找规律,例如 332,从后往前遍历,32不是单调递增将2变为9,3减1,变成了329,遍历到2,32不是递增,将2变为9,3减1,变成299,符合题目条件,打印

    2024年04月16日
    浏览(44)
  • 【力扣】84. 柱状图中最大的矩形 <模拟、双指针、单调栈>

    给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例 1: 输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10 示例 2: 输入: heights = [2,4] 输出: 4 提示

    2024年02月12日
    浏览(67)
  • 吃透单调栈(2)——解两道Hard题:接雨水、柱状图中最大的矩形问题

    这类题目的数据通常是一维数组,要寻找任一个元素的 右边或者左边 第一个 比自己 大 或者 小 的元素的位置(寻找 边界 ) ,此时我们就要想到可以用单调栈了。   这道题就是要求解每一个柱子左边第一个比它高的柱子,以及右边第一个比它高的柱子,然后这两个柱子间

    2024年02月10日
    浏览(35)
  • 【LeetCode题目详解】第八章 贪心算法 part06 738.单调递增的数字 968.监控二叉树 (day37补)

    当且仅当每个相邻位数上的数字  x  和  y  满足  x = y  时,我们称这个整数是 单调递增 的。 给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。 示例 1: 示例 2: 示例 3: 提示: 0 = n = 109 # 暴力解法 题意很简单,那么首先想的就是暴力解法了,来我替大家

    2024年02月10日
    浏览(39)
  • 算法练习--leetcode 数组

    输入n阶楼梯,每次爬1或者2个台阶,有多少种方法可以爬到楼顶? 示例1:输入2, 输出2 一次爬2阶; 一次爬1阶; 故两种方法。 示例2: 输入3, 输出3 三个1; 一个1 + 一个 2; 一个2 + 一个1; 思路分析: 采用递归求解 python实现: java实现 : 类似爬楼梯问题。   给定一个 整

    2024年02月14日
    浏览(40)
  • 算法练习Day26 (Leetcode/Python-贪心算法)

    122. Best Time to Buy and Sell Stock II You are given an integer array  prices  where  prices[i]  is the price of a given stock on the  ith  day. On each day, you may decide to buy and/or sell the stock. You can only hold  at most one  share of the stock at any time. However, you can buy it then immediately sell it on the  same day . Find and return 

    2024年02月03日
    浏览(42)
  • 【算法练习】leetcode算法题合集之二叉树篇

    前序遍历,中序遍历,后序遍历是根据处理根节点的位置来命名的。 树的处理大多用到了递归,递归需要知道终止条件。 前序遍历(中左右) 144.二叉树的前序遍历 中左右,先处理根节点,再处理左子树,再处理右子树 非递归版实现前序遍历 使用栈,当前节点处理完,先塞

    2024年02月01日
    浏览(42)
  • 算法练习 Day38 | LeetCode509,70,746

    先导知识: 1、动态规划常见题型 动态规划基础问题 背包问题 打家劫舍 股票问题 子序列问题 2、动态规划五部曲 (1)确定dp数组的定义及下标的含义 (2)确定递推公式 (3)dp数组如何初始化 (4)遍历顺序 (5)打印dp数组 LeetCode509:509. 斐波那契数 题目描述: 斐波那契

    2024年02月21日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包