LeetCode0661.图片平滑器

661图片平滑器

描述

包含整数的二维矩阵 M 表示一个图片的灰度。你需要设计一个平滑器来让每一个单元的灰度成为平均灰度 (向下舍入) ,平均灰度的计算是周围的8个单元和它本身的值求平均,如果周围的单元格不足八个,则尽可能多的利用它们。

实例

输入:
[[1,1,1],
 [1,0,1],
 [1,1,1]]
输出:
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]
解释:
对于点 (0,0), (0,2), (2,0), (2,2): 平均(3/4) = 平均(0.75) = 0
对于点 (0,1), (1,0), (1,2), (2,1): 平均(5/6) = 平均(0.83333333) = 0
对于点 (1,1): 平均(8/9) = 平均(0.88888889) = 0

注意

  1. 给定矩阵中的整数范围为 [0, 255]。
  2. 矩阵的长和宽的范围均为 [1, 150]。

题解

本题属于硬算的,唯一需要注意的是边界情况和深度或者宽度为1时的特殊处理.

代码里使用了查找表,因为灰度的分布是有限的,那么九个元素的sum也就是有限的,往往图像的像素个数远多于sum的种类,就可以把已经计算过的sum存起来,需要时进行查找.

static public int[][] imageSmoother(int[][] M) {
    int[] findTable = new int[256*9];
    int W = M[0].length;
    int H = M.length;
    int[][] result = new int[H][W];
    int sum = 0;

    if (Math.max(W,H) <=1)
        return M;
    if (W == 1){
        for (int i = 0; i < H; i++) {
            if (i == 0)
                result[i][0] = (M[i][0] + M[i+1][0])/2;
            else if (i == H-1)
                result[i][0] = (M[i][0] + M[i-1][0])/2;
            else
                result[i][0] = (M[i][0] + M[i-1][0] + M[i+1][0])/3;
        }
        return result;
    }

    if (H == 1){
        for (int i = 0; i < W; i++) {
            if (i == 0)
                result[0][i] = (M[0][i] + M[0][i+1])/2;
            else if (i == W-1)
                result[0][i] = (M[0][i] + M[0][i-1])/2;
            else
                result[0][i] = (M[0][i] + M[0][i+1] + M[0][i-1])/3;
        }
        return result;
    }

    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            if ((i == 0)&&(j == 0))
                result[i][j] = (M[i][j]+M[i+1][j]+M[i][j+1]+M[i+1][j+1])/4;
            else if ((i == 0)&&(j == W-1))
                result[i][j] = (M[i][j]+M[i+1][j]+M[i][j-1]+M[i+1][j-1])/4;
            else if (i == 0)
                result[i][j] = (M[i][j]+M[i][j-1]+M[i][j+1]+M[i+1][j]+M[i+1][j-1]+M[i+1][j+1])/6;
            else if ((i == H-1)&&(j == 0))
                result[i][j] = (M[i][j]+M[i-1][j]+M[i][j+1]+M[i-1][j+1])/4;
            else if ((i == H-1)&&(j == W-1))
                result[i][j] = (M[i][j]+M[i-1][j]+M[i][j-1]+M[i-1][j-1])/4;
            else if (i == H-1)
                result[i][j] = (M[i][j]+M[i][j-1]+M[i][j+1]+M[i-1][j]+M[i-1][j-1]+M[i-1][j+1])/6;
            else if (j == 0)
                result[i][j] = (M[i][j]+M[i-1][j]+M[i+1][j]+M[i][j+1]+M[i-1][j+1]+M[i+1][j+1])/6;
            else if (j == W-1)
                result[i][j] = (M[i][j]+M[i-1][j]+M[i+1][j]+M[i][j-1]+M[i-1][j-1]+M[i+1][j-1])/6;
            else {
                sum = M[i][j]+M[i-1][j]+M[i+1][j]+M[i][j+1]+M[i-1][j+1]+M[i+1][j+1]+M[i][j-1]+M[i-1][j-1]+M[i+1][j-1];
                if (findTable[sum] == 0){
                    findTable[sum] = sum/9;
                    result[i][j] = findTable[sum];
                } else
                    result[i][j] = findTable[sum];
            }
        }
    }

    return result;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值