The problem from LeetCode-661, “Image Smoother,” can be described as follows:
Given a 2D integer matrix M
representing an image, return a smoothed version of the image. The value of each cell in the smoothed image is the average of all the values in the corresponding 3x3 grid in the original matrix (including the cell itself). If a cell has fewer than 9 neighbors due to the edge of the matrix, the average should be calculated using the existing neighbors.
Constraints:
M
will have dimensions at most 200 × 200.M
will be in the range 0 <= M[i][j] <= 255.Before we start coding, here are some clarifying questions and assumptions:
Q: How should the averaging be handled for the borders and corners of the matrix? A: For cells on the borders and corners, consider only the available neighbors.
Q: Is the original matrix M
mutable, or should we return a new matrix as the result?
A: Return a new matrix as the result.
Q: Should the average be rounded up or down? A: The average should be floored (use integer division).
result
of the same dimensions as M
.M
:
(i, j)
, calculate the sum of the values of the 3x3 grid.[i-1, i+1]
for rows and [j-1, j+1]
for columns.result[i][j]
as the floor of the above-calculated sum divided by the number of valid cells.public class ImageSmoother {
public int[][] imageSmoother(int[][] M) {
int rows = M.length;
int cols = M[0].length;
int[][] result = new int[rows][cols];
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
result[i][j] = calculateAverage(M, i, j, rows, cols);
}
}
return result;
}
private int calculateAverage(int[][] M, int i, int j, int rows, int cols) {
int sum = 0;
int count = 0;
for (int ni = Math.max(0, i - 1); ni <= Math.min(rows - 1, i + 1); ++ni) {
for (int nj = Math.max(0, j - 1); nj <= Math.min(cols - 1, j + 1); ++nj) {
sum += M[ni][nj];
count++;
}
}
return sum / count;
}
public static void main(String[] args) {
ImageSmoother smoother = new ImageSmoother();
int[][] M = {
{1, 1, 1},
{1, 0, 1},
{1, 1, 1}
};
int[][] result = smoother.imageSmoother(M);
for (int[] row : result) {
for (int num : row) {
System.out.print(num + " ");
}
System.out.println();
}
}
}
The time complexity of this solution is O(m*n) where m
is the number of rows and n
is the number of columns in the matrix M
. This is because we iterate through each cell exactly once, and for each cell, we examine a constant number of neighbors (at most 9). The calculateAverage
function itself runs in O(1) time due to constant bounds on the neighborhood size.
Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?