解题过程
:::info
题目链接
给你一个 m x n 的矩阵 M ,初始化时所有的 0 和一个操作数组 op ,其中 ops[i] = [ai, bi] 意味着当所有的 0 <= x < ai 和 0 <= y < bi 时, M[x][y] 应该加 1。
在 执行完所有操作后 ,计算并返回 矩阵中最大整数的个数 :::
/**
* @link https://leetcode.cn/problems/range-addition-ii/
* @title 598. 范围求和 II
* @description 给你一个 m x n 的矩阵 M ,初始化时所有的 0 和一个操作数组 op ,其中 ops[i] = [ai, bi] 意味着当所有的 0 <= x < ai 和 0 <= y < bi 时, M[x][y] 应该加 1。
* 在 执行完所有操作后 ,计算并返回 矩阵中最大整数的个数
* @param {number} m
* @param {number} n
* @param {number[][]} ops
* @return {number}
*/
// 💡解法一:
// 思路:遍历ops数组,然后在遍历ai,bi可执行范围的矩阵M加1,再遍历操作后的数组统计各个数组出现的值次数,获取数组中最大值及个数
// ❌官方测试用例maxCount(39999, 39999, [19999,19999])报错(大概意思是堆内存溢出):FATAL ERROR: Committing semi space failed. Allocation failed - JavaScript heap out of memory
// 本地运行时可以的,可能官方有限制内存吧,这也说明,这种代码实现方式不友好,需要改进,所以需要优化其他代码方式实现才行
// var maxCount = function (m, n, ops) {
// const res = []
// for (let i = 0; i < ops.length; i++) {
// const ai = ops[i][0]
// const bi = ops[i][1]
// for (let j = 0; j < ai; j++) {
// for (let e = 0; e < bi; e++) {
// if (!res[j]) {
// res[j] = new Array(n).fill(0)
// res[j][e]++
// } else {
// res[j][e]++
// }
// }
// }
// }
// // 寻找最大整数值及个数
// const flatArr = res.flat().sort((a, b) => b - a) // 获取最大值
// const numMap = new Map()
// for (let i = 0; i < res.length; i++) {
// for (let j = 0; j < res[i].length; j++) {
// if (numMap.has(res[i][j])) {
// numMap.set(res[i][j], numMap.get(res[i][j]) + 1)
// } else {
// numMap.set(res[i][j], 1)
// }
// }
// }
// // 注意操作数组为空的时候的默认最大整数最大值就是矩阵M个数
// return numMap.get(flatArr[0]) || m * n
// }
// 💡解法二:
// 思路:求重叠的最小交集区域:只需找到最小的重叠区域即可,因为都是从(0, 0)点出发覆盖区域到(ai, bi),那么只需找到最小值的(aiMin, biMin)即可
var maxCount = function (m, n, ops) {
let aiMin = m
let biMin = n
for (let i = 0; i < ops.length; i++) {
// if (ops[i][0] < aiMin) {
// aiMin = ops[i][0]
// }
// if (ops[i][1] < biMin) {
// biMin = ops[i][1]
// }
aiMin = Math.min(ops[i][0], aiMin)
biMin = Math.min(ops[i][1], biMin)
}
return aiMin * biMin
}
const result = maxCount(3, 3, [[2,2],[3,3]]) // 4
// const result = maxCount(3, 3, [[2, 2], [3, 3], [3, 3], [3, 3], [2, 2], [3, 3], [3, 3], [3, 3], [2, 2], [3, 3], [3, 3], [3, 3]]) // 4
// const result = maxCount(3, 3, []) // 9
// const result = maxCount(39999, 39999, [19999,19999]) // 1599920001
console.log(result)
解题感受
想到了两种方法,第一种是本办法,以为只需要遍历所有情况计算即可,但是超出官方测试用例内存限制,不知道为啥,感觉思维还没有转变,因为最近做题没头绪的时候都会用本办法来做(穷举所有情况然后计算),没有挖掘题目更深层的含义和总结技巧规律,不过也有点难,需要多遇到类似的题型和尝试做多种解法的转换才能更好的灵活多变应用解决问题
对于类似的题型,跟昨晚做的图片平滑器也很相似,这样的二维数组,坐标(0,0)开始、重叠区域计算等关键信息是解题关键,下次需要多多注意了