Description
You are given an m x n integer matrix grid.
A rhombus sum is the sum of the elements that form the border of a regular rhombus shape in grid. The rhombus must have the shape of a square rotated 45 degrees with each of the corners centered in a grid cell. Below is an image of four valid rhombus shapes with the corresponding colored cells that should be included in each rhombus sum:
Note that the rhombus can have an area of 0, which is depicted by the purple rhombus in the bottom right corner.
Return the biggest three distinct rhombus sums in the grid in descending order. If there are less than three distinct values, return all of them.
Example 1:
Input: 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]] Output: [228,216,211] Explanation: The rhombus shapes for the three biggest distinct rhombus sums are depicted above. - Blue: 20 + 3 + 200 + 5 = 228 - Red: 200 + 2 + 10 + 4 = 216 - Green: 5 + 200 + 4 + 2 = 211
Example 2:
Input: grid = [[1,2,3],[4,5,6],[7,8,9]] Output: [20,9,8] Explanation: The rhombus shapes for the three biggest distinct rhombus sums are depicted above. - Blue: 4 + 2 + 6 + 8 = 20 - Red: 9 (area 0 rhombus in the bottom right corner) - Green: 8 (area 0 rhombus in the bottom middle)
Example 3:
Input: grid = [[7,7,7]] Output: [7] Explanation: All three possible rhombus sums are the same, so return [7].
Constraints:
m == grid.lengthn == grid[i].length1 <= m, n <= 501 <= grid[i][j] <= 105
Solutions
This function finds the three largest diagonal sums in a grid by exploring diamond-shaped regions centered at every grid position. For each position (r, c), it iterates through different diamond sizes and calculates the sum of elements along each diamond's perimeter using the calcArea helper function. The calcArea function returns null if the diamond extends beyond grid boundaries, otherwise it sums the center point, the four corner points, and all edge points along the diagonals. All unique sums are stored in a Set to eliminate duplicates, then the function sorts these sums in descending order and returns the top 3 values.
/**
* @param {number[][]} grid
* @return {number[]}
*/
var getBiggestThree = function(grid) {
const m = grid.length;
const n = grid[0].length;
const len = Math.ceil(Math.min(m, n) / 2);
const set = new Set();
const calcArea = (r, c, s) => {
const inv = s * 2;
if (r + s >= m || r - s < 0 || c + inv >= n) {
return null;
}
let sum = grid[r][c];
if (s > 0) {
sum += grid[r][c + inv];
sum += grid[r + s][c + s];
sum += grid[r - s][c + s];
}
for (let i = 1; i < s; i++) {
sum += grid[r + i][c + i];
sum += grid[r - i][c + i];
sum += grid[r + i][c + inv - i];
sum += grid[r - i][c + inv - i];
}
return sum;
};
const explore = (r, c) => {
for (let size = 0; size < len; size++) {
const area = calcArea(r, c, size);
if (area !== null) {
set.add(area);
}
}
};
for (let row = 0; row < m; row++) {
for (let col = 0; col < n; col++) {
explore(row, col);
}
}
const res = [...set].sort((a, b) => b - a);
return res.slice(0, 3);
};