Watch 10 video solutions for Image Smoother, a easy level problem involving Array, Matrix. This walkthrough by NeetCodeIO has 18,135 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
An image smoother is a filter of the size 3 x 3 that can be applied to each cell of an image by rounding down the average of the cell and the eight surrounding cells (i.e., the average of the nine cells in the blue smoother). If one or more of the surrounding cells of a cell is not present, we do not consider it in the average (i.e., the average of the four cells in the red smoother).
Given an m x n integer matrix img representing the grayscale of an image, return the image after applying the smoother on each cell of it.
Example 1:
Input: img = [[1,1,1],[1,0,1],[1,1,1]] Output: [[0,0,0],[0,0,0],[0,0,0]] Explanation: For the points (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0 For the points (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0 For the point (1,1): floor(8/9) = floor(0.88888889) = 0
Example 2:
Input: img = [[100,200,100],[200,50,200],[100,200,100]] Output: [[137,141,137],[141,138,141],[137,141,137]] Explanation: For the points (0,0), (0,2), (2,0), (2,2): floor((100+200+200+50)/4) = floor(137.5) = 137 For the points (0,1), (1,0), (1,2), (2,1): floor((200+200+50+200+100+100)/6) = floor(141.666667) = 141 For the point (1,1): floor((50+200+200+200+200+100+100+100+100)/9) = floor(138.888889) = 138
Constraints:
m == img.lengthn == img[i].length1 <= m, n <= 2000 <= img[i][j] <= 255Problem Overview: You receive a 2D matrix representing a grayscale image. For every pixel, compute the average of that pixel and all valid neighbors in its surrounding 3×3 region. Out-of-bounds neighbors are ignored, and the final value is the floor of the average.
Approach 1: Brute Force with Neighbor Validation (Time: O(m*n), Space: O(m*n))
The direct solution iterates through every cell of the matrix and inspects up to 8 surrounding neighbors plus the cell itself. For each position (i, j), loop through the relative offsets -1..1 for rows and columns to examine the 3×3 region. During the scan, check bounds to ensure the neighbor exists inside the grid before adding its value to the running sum and incrementing the count. The smoothed pixel value becomes sum // count. This method is straightforward and easy to reason about, making it ideal for interviews where correctness and clarity matter. The algorithm touches each pixel once and inspects at most 9 cells, so the total time complexity is O(m*n). The output matrix requires O(m*n) space. This approach relies heavily on simple iteration over a matrix and basic array traversal.
Approach 2: Iterative with Sliding Window Optimization (Time: O(m*n), Space: O(1) extra)
You can reduce repeated neighbor checks by treating the 3×3 neighborhood as a sliding window across each row. Instead of recomputing all surrounding values from scratch, maintain partial sums while moving horizontally. As the window shifts from column j to j+1, subtract the values leaving the left edge of the window and add the values entering from the right edge. Boundary handling still applies for the first and last columns, but most computations are reused. This reduces constant overhead and improves cache locality while keeping the same asymptotic complexity. The algorithm still processes each pixel once, so time complexity remains O(m*n), while auxiliary memory stays O(1) beyond the output grid. This pattern appears frequently in grid problems involving neighborhood aggregation in a matrix.
Recommended for interviews: Start with the brute force neighbor validation approach. It clearly demonstrates you understand how to traverse a grid and handle boundary conditions. Once that works, mention the sliding window idea to reduce repeated calculations. Interviewers usually expect the brute force implementation since its time complexity is already optimal at O(m*n), but discussing optimization shows deeper familiarity with grid processing patterns.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force with Neighbor Validation | O(m*n) | O(m*n) | Best for interviews and clarity. Simple implementation that directly checks the 3×3 neighborhood. |
| Iterative Sliding Window Optimization | O(m*n) | O(1) extra | Useful when minimizing repeated calculations across adjacent columns or improving cache efficiency. |