2021-03-20:给定一个二维数组matrix,其中的值不是0就是1,返回全部由1组成的子矩形数
2021-03-20 23:07
766 查看
2021-03-20:给定一个二维数组matrix,其中的值不是0就是1,返回全部由1组成的子矩形数量。
福大大 答案2021-03-20:
按行遍历二维数组,构造直方图。
单调栈,大压小。有代码。
代码用golang编写,代码如下:
package main import "fmt" func main() { matrix := [][]int{ {1, 1, 1, 1, 1, 1}, } ret := numSubmat(matrix) fmt.Println(ret) } func numSubmat(mat [][]int) int { if len(mat) == 0 || len(mat[0]) == 0 { return 0 } nums := 0 height := make([]int, len(mat[0])) for i := 0; i < len(mat); i++ { for j := 0; j < len(mat[0]); j++ { if mat[i][j] == 0 { height[j] = 0 } else { height[j]++ } } nums += countFromBottom(height) } return nums } func countFromBottom(height []int) int { if len(height) == 0 { return 0 } nums := 0 stack := make([]int, len(height)) si := -1 for i := 0; i < len(height); i++ { for si != -1 && height[stack[si]] >= height[i] { cur := stack[si] si-- if height[cur] > height[i] { left := -1 if si != -1 { left = stack[si] } n := i - left - 1 heightleft := 0 if left != -1 { heightleft = height[left] } down := getMax(heightleft, height[i]) nums += (height[cur] - down) * num(n) } } si++ stack[si] = i } for si != -1 { cur := stack[si] si-- left := -1 if si != -1 { left = stack[si] } n := len(height) - left - 1 down := 0 if left != -1 { down = height[left] } nums += (height[cur] - down) * num(n) } return nums } func num(n int) int { return (n * (1 + n)) >> 1 } func getMax(a int, b int) int { if a > b { return a } else { return b } }
执行结果如下:
相关文章推荐
- 有一个直方图,用一个整数数组表示,其中每列的宽度为1,求所给直方图包含的最大矩形面积。比如,对于直方图[2,7,9,4],它所包含的最大矩形的面积为14(即[7,9]包涵的7x2的矩形)。给定一个直方图A及它的总宽度n,请返回最大矩形面积。保证直方图宽度小于等于500。保证结果在int范围内。
- 给定一个N位的数,返回由这N个数组成的比原来的数大数中的最小的数
- 有一个int型数组,每两个相邻的数之间的差值不是1就是-1.现在给定一个数,要求查找这个数在数组中的位置
- 剑指offer——给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
- 5.7 编写一个程序,其中有一个函数指针*parea,通过它分别指向计算圆的面积函数 circle 和矩形面积函数 rect 来计算给定圆的面积和矩形面积。
- 在一个字符串(1<=字符串长度<=10000,全部由大小写字母组成)中找到第一个只出现一次的字符,并返回它的位置
- 在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置
- 算法22:给定一个排好序的linked list,删除其中所有的重复元素。比如给定1->2->3->3-> 4->4->5,返回1->2->5。给定1->1->1->2->3,返回2->3
- 【剑指Offer-时间效率平衡】在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置
- 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回
- 实现一个判断素数的简单函数、以及利用该函数计算给定区间内素数和的函数。素数就是只能被1和自身整除的正整数。注意:1不是素数,2是素数
- 谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
- 给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
- 空格替换 请编写一个方法,将字符串中的空格全部替换为“%20”。假定该字符串有足够的空间存放新增的字符,并且知道字符串的真实长度(小于等于1000),同时保证字符串由大小写的英文字母组成。 给定一
- 链式A+B有两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表的首部。编写函数对这两个整数求和,并用链表形式返回结果。 给定两个链表ListNode* A,ListN
- 经典算法 | 给定n个矩形,判断这些矩形是否在不重合的情况下组成一个大矩形的算法
- 华为机试题----比较二维数组列最小值,组成一个新数组返回
- 一个由24个字母组成的数组,其中每个字符出现3次(也就是8组相同字母,混序放在一个数组中),用程序实现将相同字母的下标存入一个8*3的数组中
- 给出a-z0-9,在其中选择三个字符组成一个密码,输出全部的情况,程序实现
- 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。