Maximum Number of Ones
Hard · Heap / Priority Queue · Explanation and code example
Optimally Fill the Remainder Grids
How it works
Instead of computing and sorting all positions, we can directly calculate the answer by analyzing the structure of the tiled matrix. The matrix divides into regions based on how the sideLength pattern tiles:
- Full tiles that appear
(height / sideLength) * (width / sideLength)times. - Partial tiles along the right edge, bottom edge, and bottom-right corner.
Positions in the corner remainder region (bottom-right) appear the most frequently because they get counted in the main grid plus both edge strips plus the corner. We should fill these first, then the positions in the edge strips, prioritizing the edge with more repetitions.
Steps
- Start by placing
maxOnesones in the fully repeated grid sections, contributingmaxOnes * (height / sideLength) * (width / sideLength)ones. - Fill positions in the corner remainder region first (size =
(height % sideLength) * (width % sideLength)). Each such position contributes to all three remainder regions plus the main grid. - Based on which dimension has more full tiles, fill the appropriate edge strip next.
- Fill the remaining edge strip with any leftover positions.
- Return the total count.
Complexity
-
Time complexity:
O(1) -
Space complexity:
O(1)
Things to watch for
Misunderstanding the Tiling Pattern
The constraint applies to every sideLength x sideLength submatrix, not just non-overlapping tiles. This means adjacent submatrices overlap, creating a repeating pattern where each position (r, c) in the pattern maps to the same relative position (r % sideLength, c % sideLength) across the entire matrix.
Incorrect Frequency Calculation
When calculating how many times a position in the pattern appears in the full matrix, you must account for partial tiles at the edges. The formula (1 + (width - c - 1) / sideLength) handles this, but off-by-one errors are common. Using (width - c) / sideLength or similar incorrect formulas will give wrong counts.
Swapping Width and Height
The problem distinguishes between width (columns) and height (rows). Confusing these dimensions when calculating horizontal and vertical repetitions leads to incorrect frequency counts, especially when the matrix is not square.
Greedy Selection Order
After computing frequencies, you must select the maxOnes positions with the highest frequencies. Forgetting to sort in descending order or selecting positions with lower frequencies will not maximize the total number of ones in the matrix.
Python code example
class Solution:
def maximumNumberOfOnes(self, width: int, height: int, sideLength: int, maxOnes: int) -> int:
answer = maxOnes * ((height // sideLength) * (width // sideLength))
remain = maxOnes
cnt1 = min((height % sideLength) * (width % sideLength), remain)
answer += ((height // sideLength) + (width // sideLength) + 1) * cnt1
remain -= cnt1
if height // sideLength > width // sideLength:
cnt2 = min(((width % sideLength) * sideLength) - ((height % sideLength) * (width % sideLength)), remain)
answer += (height // sideLength) * cnt2
remain -= cnt2
cnt3 = min(((height % sideLength) * sideLength) - ((height % sideLength) * (width % sideLength)), remain)
answer += (width // sideLength) * cnt3
remain -= cnt3
else:
cnt2 = min(((height % sideLength) * sideLength) - ((height % sideLength) * (width % sideLength)), remain)
answer += (width // sideLength) * cnt2
remain -= cnt2
cnt3 = min(((width % sideLength) * sideLength) - ((height % sideLength) * (width % sideLength)), remain)
answer += (height // sideLength) * cnt3
remain -= cnt3
return answer
C++ code example
class Solution {
public:
int maximumNumberOfOnes(int width, int height, int sideLength, int maxOnes) {
int answer = maxOnes * ((height / sideLength) * (width / sideLength));
int remain = maxOnes;
int cnt1 = min((height % sideLength) * (width % sideLength), remain);
answer += ((height / sideLength) + (width / sideLength) + 1) * cnt1;
remain -= cnt1;
if (height / sideLength > width / sideLength) {
int cnt2 = min(((width % sideLength) * sideLength) - ((height % sideLength) * (width % sideLength)), remain);
answer += (height / sideLength) * cnt2;
remain -= cnt2;
int cnt3 = min(((height % sideLength) * sideLength) - ((height % sideLength) * (width % sideLength)), remain);
answer += (width / sideLength) * cnt3;
remain -= cnt3;
} else {
int cnt2 = min(((height % sideLength) * sideLength) - ((height % sideLength) * (width % sideLength)), remain);
answer += (width / sideLength) * cnt2;
remain -= cnt2;
int cnt3 = min(((width % sideLength) * sideLength) - ((height % sideLength) * (width % sideLength)), remain);
answer += (height / sideLength) * cnt3;
remain -= cnt3;
}
return answer;
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.