class Solution:
def maximumNumberOfOnes(self, width: int, height: int, sideLength: int, maxOnes: int) -> int:
from collections import Counter
freq = Counter()
for i in range(sideLength):
for j in range(sideLength):
# Count how many times each position in the sideLength x sideLength block appears
freq[(i, j)] = ((height - i + sideLength - 1) // sideLength) * ((width - j + sideLength - 1) // sideLength)
# Take the maxOnes positions with the largest frequency
return sum(cnt for _, cnt in sorted(freq.items(), key=lambda x: -x[1])[:maxOnes])
class Solution {
public:
int maximumNumberOfOnes(int width, int height, int sideLength, int maxOnes) {
vector<int> freq;
for (int i = 0; i < sideLength; ++i) {
for (int j = 0; j < sideLength; ++j) {
int count = ((height - i + sideLength - 1) / sideLength) * ((width - j + sideLength - 1) / sideLength);
freq.push_back(count);
}
}
sort(freq.begin(), freq.end(), greater<int>());
int res = 0;
for (int i = 0; i < maxOnes; ++i) {
res += freq[i];
}
return res;
}
};
class Solution {
public int maximumNumberOfOnes(int width, int height, int sideLength, int maxOnes) {
List<Integer> freq = new ArrayList<>();
for (int i = 0; i < sideLength; i++) {
for (int j = 0; j < sideLength; j++) {
int count = ((height - i + sideLength - 1) / sideLength) * ((width - j + sideLength - 1) / sideLength);
freq.add(count);
}
}
Collections.sort(freq, Collections.reverseOrder());
int res = 0;
for (int i = 0; i < maxOnes; i++) {
res += freq.get(i);
}
return res;
}
}
var maximumNumberOfOnes = function(width, height, sideLength, maxOnes) {
let freq = [];
for (let i = 0; i < sideLength; i++) {
for (let j = 0; j < sideLength; j++) {
let count = Math.floor((height - i + sideLength - 1) / sideLength) * Math.floor((width - j + sideLength - 1) / sideLength);
freq.push(count);
}
}
freq.sort((a, b) => b - a);
let res = 0;
for (let i = 0; i < maxOnes; i++) {
res += freq[i];
}
return res;
};
width
, height
, sideLength
, and maxOnes
.
Your task is to construct a height x width
binary matrix (filled with 0s and 1s) such that:
sideLength x sideLength
sub-square of the matrix, there are at most maxOnes
ones in that square.sideLength x sideLength
sub-square must have at most maxOnes
ones.sideLength x sideLength
constraint is satisfied. However, this approach is infeasible for large matrices due to the exponential number of possibilities.
Upon closer inspection, you can notice a repeating pattern: every sideLength x sideLength
block overlaps in a regular, tiled fashion. Thus, the problem is about optimally distributing ones within a single sideLength x sideLength
block and replicating this pattern across the entire matrix.
The key is to place ones in the most "frequent" positions within the block — the positions that appear most often in the overall matrix. By prioritizing these, you maximize the total number of ones.
sideLength x sideLength
blocks:
sideLength x sideLength
blocks. The pattern in each block will repeat throughout the matrix.(i, j)
in the block, calculate how many times it will appear in the overall matrix. This is determined by how many times the block "fits" across the width and height.maxOnes
most frequent positions and set them to 1 in the block pattern.maxOnes
constraint for every block.
width = 3
, height = 3
, sideLength = 2
, maxOnes = 2
.
maxOnes = 2
).O(2^{width \times height})
.sideLength x sideLength
block, which is at most 400 positions (if sideLength=20
).O(1)
.O(sideLength^2 \log sideLength^2)
.O(sideLength^2 \log sideLength^2)
.O(sideLength^2)
for storing frequencies.maxOnes
), we achieve the optimal solution efficiently. This approach elegantly reduces a seemingly complex problem to a manageable, pattern-based calculation.