矩阵中最大的三个菱形和
难度:
标签:
题目描述
给你一个 m x n
的整数矩阵 grid
。
菱形和 指的是 grid
中一个正菱形 边界 上的元素之和。本题中的菱形必须为正方形旋转45度,且四个角都在一个格子当中。下图是四个可行的菱形,每个菱形和应该包含的格子都用了相应颜色标注在图中。

注意,菱形可以是一个面积为 0 的区域,如上图中右下角的紫色菱形所示。
请你按照 降序 返回 grid
中三个最大的 互不相同的菱形和 。如果不同的和少于三个,则将它们全部返回。
示例 1:

输入:grid = [[3,4,5,1,3],[3,3,4,2,3],[20,30,200,40,10],[1,5,5,4,1],[4,3,2,2,5]] 输出:[228,216,211] 解释:最大的三个菱形和如上图所示。 - 蓝色:20 + 3 + 200 + 5 = 228 - 红色:200 + 2 + 10 + 4 = 216 - 绿色:5 + 200 + 4 + 2 = 211
示例 2:

输入:grid = [[1,2,3],[4,5,6],[7,8,9]] 输出:[20,9,8] 解释:最大的三个菱形和如上图所示。 - 蓝色:4 + 2 + 6 + 8 = 20 - 红色:9 (右下角红色的面积为 0 的菱形) - 绿色:8 (下方中央面积为 0 的菱形)
示例 3:
输入:grid = [[7,7,7]] 输出:[7] 解释:所有三个可能的菱形和都相同,所以返回 [7] 。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 100
1 <= grid[i][j] <= 105
代码结果
运行时间: 306 ms, 内存: 16.7 MB
/*
* Problem: Find the three largest unique rhombus sums in a given 2D grid using Java Streams.
* A rhombus is defined as a square rotated 45 degrees. The sum of a rhombus is the sum of all the elements on its boundary.
* Approach:
* 1. Use streams to iterate through each possible center of the rhombus and calculate all possible rhombus sums.
* 2. Store unique sums in a set and sort them in descending order.
* 3. Return the top three unique sums.
*/
import java.util.*;
import java.util.stream.*;
public class RhombusSumsStream {
public List<Integer> getBiggestThree(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
Set<Integer> uniqueSums = IntStream.range(0, m)
.boxed()
.flatMap(i -> IntStream.range(0, n)
.boxed()
.flatMap(j -> IntStream.range(0, Math.min(Math.min(i, j), Math.min(m - i - 1, n - j - 1)) + 1)
.map(size -> calculateRhombusSum(grid, i, j, size))
.boxed()))
.collect(Collectors.toSet());
return uniqueSums.stream()
.sorted(Comparator.reverseOrder())
.limit(3)
.collect(Collectors.toList());
}
private int calculateRhombusSum(int[][] grid, int i, int j, int size) {
int sum = 0;
for (int k = 0; k <= size; k++) {
sum += grid[i - k][j + k];
sum += grid[i + k][j + k];
sum += grid[i + k][j - k];
sum += grid[i - k][j - k];
}
if (size > 0) {
sum -= grid[i][j - size];
sum -= grid[i][j + size];
sum -= grid[i - size][j];
sum -= grid[i + size][j];
}
return sum;
}
}
解释
方法:
本题解的主要思路是使用动态规划来计算矩阵中任意菱形的和。首先,构建两个辅助矩阵sum1和sum2来存储从左上到右下和从右上到左下的前缀和。这样可以快速计算出任意大小的菱形和。对于每个可能的菱形中心点,遍历可能的菱形大小,利用前缀和矩阵来计算出这个菱形的总和。使用一个自定义类Answer来维护三个最大的不同的菱形和。这个类有一个方法put来更新这三个最大值,如果新的菱形和比已有的大且不重复,则更新对应的值。最后,使用get方法返回结果。这种方法可以有效地避免重复计算任意菱形的元素和,提高效率。
时间复杂度:
O(m*n*min(m,n)^2)
空间复杂度:
O(m*n)
代码细节讲解
🦆
在构建前缀和矩阵sum1和sum2时,为什么一个从左上到右下,另一个从右上到左下,这样的设计有什么特别的优势吗?
▷🦆
如何确保在计算过程中不会重复计算相同大小和位置的菱形和?
▷🦆
在Answer类的put方法中,如何处理新加入的菱形和与已存在的菱形和相等的情况?
▷🦆
在计算菱形和时,减去的(grid[ux][uy] + grid[dx][dy] + grid[lx][ly] + grid[rx][ry])是为了什么目的?这些元素被重复计算了吗?
▷