Image Smoother LT661

Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surrounding cells and itself. If a cell has less than 8 surrounding cells, then use as many as you can.

Example 1:

Input:
[[1,1,1],
 [1,0,1],
 [1,1,1]]
Output:
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]
Explanation:
For the point (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0
For the point (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


Note:

    1. The value in the given matrix is in the range of [0, 255].
    2. The length and width of the given matrix are in the range of [1, 150].

 Idea 1. Bruteforce, it's straightforward with auxiliary space, loop the old value from the input matrix.

Time complexity: O(M * N)

Space complexity: O(M * N)

 1 class Solution {
 2     public int[][] imageSmoother(int[][] M) {
 3         int M1  = M.length;
 4         int N1 = M[0].length;
 5         
 6         int[][] dirs = {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
 7         
 8         int[][] result = new int[M1][N1];
 9         for(int i = 0; i < M1; ++i) {
10             for(int j = 0; j < N1; ++j) {
11                 int count = 0;
12                 for(int[] d : dirs) {
13                     int nextX = i + d[0];
14                     int nextY = j + d[1];
15                     if(nextX >= 0 && nextX < M1 && nextY >= 0 && nextY < N1) {
16                         ++count;
17                         result[i][j] += M[nextX][nextY];
18                     } 
19                 }
20                 result[i][j] += M[i][j];
21                 result[i][j] /= (count + 1);
22             }
23         }
24         
25         return result;
26     }
27 }

Another way to loop the negighbours, including itself

 1 class Solution {
 2     public int[][] imageSmoother(int[][] M) {
 3         int M1  = M.length;
 4         int N1 = M[0].length;
 5                 
 6         int[][] result = new int[M1][N1];
 7         for(int i = 0; i < M1; ++i) {
 8             for(int j = 0; j < N1; ++j) {
 9                 int count = 0;
10                 for(int nextR = i-1; nextR <= i+1; ++nextR) {
11                     for(int nextC = j-1; nextC <= j+1; ++nextC) {
12                         if(nextR >= 0 && nextR < M1 && nextC >= 0 && nextC < N1) {
13                             ++count;
14                             result[i][j] += M[nextR][nextC];
15                         }
16                     }
17                 } 
18                 result[i][j] /= count;
19             }
20         }
21         
22         return result;
23     }
24 }

Idea 2. in-place calculation, keeping the old value and updated value in the same M[i][j], since old value M[i][j] is in the range [0, 255], which can be represented by 8 bits (2^8 -1 = 255), a integer has 32 bits, hence from left to right, the first 8 bits stores the old value, the second 8 bits stores the updated value, once all the calculation is done, remove the old value by shifting the integer 8 bits to the right.

Note: 0xFF = 255, F = 15 = 1111

Time complexity: O(M * N)

Space complexity: O(1)

 1 class Solution {
 2     public int[][] imageSmoother(int[][] M) {
 3         int M1  = M.length;
 4         int N1 = M[0].length;
 5                 
 6         int mask = 0xFF;
 7         for(int i = 0; i < M1; ++i) {
 8             for(int j = 0; j < N1; ++j) {
 9                 int count = 0;
10                 int sum = 0;
11                 
12                 for(int nextR = i-1; nextR <= i+1; ++nextR) {
13                     for(int nextC = j-1; nextC <= j+1; ++nextC) {
14                         if(nextR >= 0 && nextR < M1 && nextC >= 0 && nextC < N1) {
15                             ++count;
16                             sum += (M[nextR][nextC] & mask);
17                         }
18                     }
19                 } 
20                 
21                 M[i][j] |= (sum/count) << 8;
22             }
23         }
24         
25         for(int i = 0; i < M1; ++i) {
26             for(int j = 0; j < N1; ++j) {
27                 M[i][j] >>= 8;
28             }
29         }
30         
31         return M;
32     }
33 }

猜你喜欢

转载自www.cnblogs.com/taste-it-own-it-love-it/p/10842336.html