【神奇的技巧】leetcode - 661. Image Smoother【整数位信息使用 + 二维数组边界考虑 + 数组的巧妙使用】
2017-08-20 16:55
561 查看
题目
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 surroundingcells, 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:
The value in the given matrix is in the range of [0, 255].
The length and width of the given matrix are in the range of [1, 150].
分析及解答
解法:(简洁)大神:stefanpochmann
I store the sums and counts in the higher bits and divide them in a second pass.
public int[][] imageSmoother(int[][] M) { int m = M.length, n = M[0].length; for (int i=0; i<m; i++) for (int j=0; j<n; j++) for (int I=i-1; I<i+2; I++) for (int J=j-1; J<j+2; J++) if (I >= 0 && I < m && J >= 0 && J < n) M[i][j] += 256 + M[I][J] % 256 * 4096; for (int i=0; i<m; i++) for (int j=0; j<n; j++) M[i][j] = M[i][j] / 4096 / (M[i][j] / 256 % 16); return M; }
After my first pass, each M[i][j] holds:
In bits 0-7: The original value.
In bits 8-11: The number of contributing cells (i.e., the number of neighbors, plus 1 (for the cell itself)). That's why I add 256 for each contributing cell.
In bits 12-31: The sum of the original values of the contributing cells. That's why I add the original value of M[I][J] times 4096.
解法:(下面反例的改进)
class Solution { public int[][] imageSmoother(int[][] M) { if(M==null || M.length<1){ return null; } int[][] array = new int[M.length][M[0].length]; int[][] dirs = new int[][]{{-1,0},{1,0},{0,1},{0,-1},{-1,-1},{-1,1},{1,1},{1,-1}};//巧妙的数组设置。 for(int i=0;i<M.length;i++){ for(int j=0;j<M[0].length;j++){ int sum=M[i][j]; int count =1; for(int [] dir:dirs){ //使用数组。 int x=i+dir[0]; int y=j+dir[1]; if(x<0 || x>=M.length || y<0 || y>=M[0].length){ //判断四周的数组是否有效。 continue; }else{ count++; sum+=M[x][y]; } } array[i][j] = sum/count; } } return array; } }
解法:(反例:垃圾的算法)
分为好几次遍历:
* 每个元素影响其下面的元素。
*每个元素影响其上面的元素。
*每个元素影响其斜对角的元素。
class Solution { public int[][] imageSmoother(int[][] M) { if(M.length == 1 && M[0].length == 1){ return M; } //1.让每个results中的单元,保留周围元素的和。 int results[][] = new int[M.length][M[0].length]; for(int i = 0; i < M.length ; i++){ for(int j = 0; j < M[0].length ;j++){ results[i][j] = M[i][j]; } } // 从左向右 for(int i = 0; i < M.length ; i++){ for(int j = 0; j < M[0].length ;j++){ if(i < M.length -1){ results[i+1][j] += M[i][j]; } if(j < M[0].length-1){ results[i][j+1] += M[i][j]; } if(i < M.length -1 && j < M[0].length-1){ results[i+1][j+1] += M[i][j]; } } } //从右向左,每个节点去影响周围的元素。 for(int i = M.length -1; i >= 0;i--){ for(int j = M[0].length - 1; j >= 0;j--){ if(i > 0){ results[i-1][j] += M[i][j]; } if(j > 0){ results[i][j-1] += M[i][j]; if(i > 0 && j > 0){ results[i-1][j-1] += M[i][j]; } } } } //影响斜对角。 for(int i = 0; i < M.length ; i++){ for(int j = 0; j < M[0].length ;j++){ if(i+1 <= M.length -1 && j-1 >= 0){ results[i+1][j-1] += M[i][j]; } if(i-1 >=0 && j+1 <= M[0].length -1){ results[i-1][j+1] += M[i][j]; } }} //2.计算平均值。 for(int i = 0; i < M.length ; i++){ for(int j = 0; j < M[0].length ;j++){ int count = 9;//记录周围元素的数量 int row = 0; if(i == 0){ count -= 3;//顶行,去除3个元素 row++; } if(i == M.length-1){ count -= 3;//最底行,去除3个元素 row++; } if(j == 0){ count -=3;//最左列,去除3个元素 count += row;//加上多去的。(行与列产生了交叉) } if(j == M[0].length-1){ count -= 3; count += row; } results[i][j] = results[i][j]/count; } } return results; } }
相关文章推荐
- vim技巧 - 替换的巧妙使用(1)
- vim技巧 - 替换的巧妙使用(3)
- GridView使用技巧之:新增记录、GridView内数据验证、删除信息提示等
- Java数组特点及基本使用技巧
- 看代码学技术-JavaScript数组使用技巧
- [转载] Vim技巧 - 替换的巧妙使用
- 《GOOGLE HACKS巧妙使用网络搜索的技巧和工具(第二版)》
- linux shell 数组建立及使用技巧
- linux shell 数组建立及使用技巧
- 二维数组做函数参数,如何将三维数组降为二维数组,指向数组的指针的使用
- PHP数组操作汇总 php数组的使用技巧
- PHP数组操作汇总 php数组的使用技巧
- bash shell数组模拟队列queue和shell数组使用技巧
- 【技巧】不使用外部工具也能检测内存的物理信息
- Java数组特点及基本使用技巧
- linux shell 数组建立及使用技巧
- vim技巧 - 替换的巧妙使用(2)
- linux shell 动态生成 数组系列 seq使用技巧
- 函数模板中使用二维数组作为参数时的技巧
- 新手入门:Java数组特点及基本使用技巧