Get Biggest Three Rhombus Sums in a Grid

MEDIUM

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.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • 1 <= grid[i][j] <= 105

Approaches

Checkout 2 different approaches to solve Get Biggest Three Rhombus Sums in a Grid. Click on different approaches to view the approach and algorithm in detail.

Brute-Force Simulation

This approach directly simulates the process of finding every possible rhombus in the grid. We iterate through each cell as a potential center of a rhombus. For each center, we expand outwards to form rhombuses of increasing sizes, as long as they stay within the grid boundaries. For each valid rhombus, we calculate its sum by traversing its border and adding up the cell values.

Algorithm

  • Initialize a TreeSet called sums to store distinct rhombus sums in sorted order.
  • Iterate through each cell (r, c) from (0, 0) to (m-1, n-1) to use as a rhombus center.
  • For each center (r, c):
    • Add grid[r][c] to sums (this is a rhombus of size 0).
    • Start a loop for rhombus size k from 1.
    • Check if a rhombus of size k centered at (r, c) is fully contained within the grid. If not, break the loop for k.
    • If it is contained, calculate the sum of its border elements by iterating along its four sides.
    • Add the calculated sum to sums.
  • After all iterations, sums will contain all distinct rhombus sums.
  • Create a result array of size min(3, sums.size()).
  • Pop the largest elements from sums and fill the result array.
  • Return the result array.

We use a TreeSet to store the distinct rhombus sums. A TreeSet is useful because it automatically keeps the sums sorted and handles duplicates.

We iterate through every cell (r, c) of the grid. This cell will serve as the center of a potential rhombus.

For each center (r, c), we first consider a rhombus of size 0. The sum is simply the value of the cell grid[r][c]. We add this to our set.

Then, we start a loop for the rhombus size k, starting from k=1. We expand the rhombus as long as its four corners (r-k, c), (r, c+k), (r+k, c), and (r, c-k) are all within the grid's boundaries.

For each valid size k, we calculate the sum of the elements on its border. This is done by simulating a walk along the four sides of the rhombus, taking care not to double-count the corner elements.

The calculated sum is added to the TreeSet.

After checking all possible centers and sizes, the TreeSet contains all distinct rhombus sums in ascending order. We extract the top three largest sums (or fewer if there aren't that many) and return them in descending order.

import java.util.*;

class Solution {
    public int[] getBiggestThree(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        // Use a TreeSet to keep sums sorted and unique
        TreeSet<Integer> sums = new TreeSet<>();

        for (int r = 0; r < m; r++) {
            for (int c = 0; c < n; c++) {
                // Size 0 rhombus
                sums.add(grid[r][c]);

                // Size k > 0 rhombuses
                for (int k = 1; ; k++) {
                    // Check if the rhombus is within bounds
                    if (r - k < 0 || r + k >= m || c - k < 0 || c + k >= n) {
                        break;
                    }

                    // Calculate sum for rhombus of size k
                    int currentSum = 0;
                    // Top to right (excluding right corner)
                    for (int i = 0; i < k; i++) {
                        currentSum += grid[r - k + i][c + i];
                    }
                    // Right to bottom (excluding bottom corner)
                    for (int i = 0; i < k; i++) {
                        currentSum += grid[r + i][c + k - i];
                    }
                    // Bottom to left (excluding left corner)
                    for (int i = 0; i < k; i++) {
                        currentSum += grid[r + k - i][c - i];
                    }
                    // Left to top (excluding top corner)
                    for (int i = 0; i < k; i++) {
                        currentSum += grid[r - i][c - k + i];
                    }
                    sums.add(currentSum);
                }
            }
        }

        // Extract the top 3 sums
        int count = Math.min(3, sums.size());
        int[] result = new int[count];
        for (int i = 0; i < count; i++) {
            result[i] = sums.pollLast();
        }
        return result;
    }
}

Complexity Analysis

Time Complexity: O(m * n * min(m, n)^2). We iterate through `m * n` possible centers. For each center, we iterate through possible rhombus sizes `k`, where the maximum `k` is `O(min(m, n))`. For each size `k`, calculating the sum takes `O(k)` time. For a square grid of size `N`, this is `O(N^4)`.Space Complexity: O(m * n * min(m, n)). In the worst case, every rhombus could have a unique sum. The number of possible rhombuses is O(m * n * min(m, n)). The `TreeSet` would store all these sums.

Pros and Cons

Pros:
  • Conceptually simple and follows the problem definition directly.
  • Relatively easy to implement without complex data structures.
Cons:
  • Highly inefficient due to redundant calculations. The sum for each rhombus is computed from scratch.
  • May be too slow for larger grid sizes, although it passes for the given constraints (m, n <= 50).

Code Solutions

Checking out 3 solutions in different languages for Get Biggest Three Rhombus Sums in a Grid. Click on different languages to view the code.

class Solution {
public
  int[] getBiggestThree(int[][] grid) {
    int m = grid.length, n = grid[0].length;
    int[][] s1 = new int[m + 1][n + 2];
    int[][] s2 = new int[m + 1][n + 2];
    for (int i = 1; i <= m; ++i) {
      for (int j = 1; j <= n; ++j) {
        s1[i][j] = s1[i - 1][j - 1] + grid[i - 1][j - 1];
        s2[i][j] = s2[i - 1][j + 1] + grid[i - 1][j - 1];
      }
    }
    TreeSet<Integer> ss = new TreeSet<>();
    for (int i = 1; i <= m; ++i) {
      for (int j = 1; j <= n; ++j) {
        int l = Math.min(Math.min(i - 1, m - i), Math.min(j - 1, n - j));
        ss.add(grid[i - 1][j - 1]);
        for (int k = 1; k <= l; ++k) {
          int a = s1[i + k][j] - s1[i][j - k];
          int b = s1[i][j + k] - s1[i - k][j];
          int c = s2[i][j - k] - s2[i - k][j];
          int d = s2[i + k][j] - s2[i][j + k];
          ss.add(a + b + c + d - grid[i + k - 1][j - 1] +
                 grid[i - k - 1][j - 1]);
        }
        while (ss.size() > 3) {
          ss.pollFirst();
        }
      }
    }
    int[] ans = new int[ss.size()];
    for (int i = 0; i < ans.length; ++i) {
      ans[i] = ss.pollLast();
    }
    return ans;
  }
}

Video Solution

Watch the video walkthrough for Get Biggest Three Rhombus Sums in a Grid



Algorithms:

Sorting

Patterns:

MathPrefix Sum

Data Structures:

ArrayHeap (Priority Queue)Matrix

Subscribe to Scale Engineer newsletter

Learn about System Design, Software Engineering, and interview experiences every week.

No spam, unsubscribe at any time.