Thursday, August 24, 2017

661. Image Smoother

https://leetcode.com/problems/image-smoother/description/
Solution 0. Use the bits at the same address to store the sum and counts
    vector<vector<int>> imageSmoother(vector<vector<int>>& M) {
        int L = M.size();
        int W = M[0].size();

        for(int i=0;i<L;i++){

            for(int j=0;j<W;j++){
                for(int m=i-1;m<=i+1;m++) {
                    for(int n=j-1;n<=j+1;n++) {
                        if(m>=0 && m<L && n>=0 && n<W) {
                            // bits 0~7: 255 = 11111111b
                            // original value = M[m][n] & 255
                            // bits 8~11: counts 
                            // 256 = 100000000b
                            // bits 12~ : sum
                            M[i][j] += 256 + ((M[m][n]&255) << 12);
                        }
                    }
                }
            }
        }
        for(int i=0;i<L;i++){
            for(int j=0;j<W;j++){
                // 15 = 1111b, use & to get the counts
                M[i][j] = (M[i][j]>>12)/((M[i][j]>>8) & 15);
            }
        }
        return M;
    }
Solution 1. A boring solution.
    vector<vector<int>> imageSmoother(vector<vector<int>>& M) {
        vector<vector<int>> res(M);
        int L = M.size();
        if(L==0) return res;      
        int W = M[0].size();
        if(W==0) return res;
     
        vector<vector<int>> cnt(L+2, vector<int>(W+2,1));
        vector<vector<int>> val(L+2, vector<int>(W+2));
        for(int i=0;i<L+2;i++) {
            cnt[i][0] = 0;
            cnt[i][W+1] = 0;
        }
        for(int j=0;j<W+2;j++) {
            cnt[0][j] = 0;
            cnt[L+1][j] = 0;
        }
        for(int i=1;i<L+1;i++){
            for(int j=1;j<W+1;j++){
                val[i][j] = M[i-1][j-1];
            }
        }
        for(int i=1;i<L+1;i++){
            for(int j=1;j<W+1;j++){
                res[i-1][j-1] =
                    ( val[i-1][j-1] + val[i-1][j] + val[i-1][j+1]
                    + val[i][j-1] +   val[i][j] +   val[i][j+1]
                    + val[i+1][j-1] + val[i+1][j] + val[i+1][j+1]) /
                    ( cnt[i-1][j-1] + cnt[i-1][j] + cnt[i-1][j+1]
                    + cnt[i][j-1] +   cnt[i][j] +   cnt[i][j+1]
                    + cnt[i+1][j-1] + cnt[i+1][j] + cnt[i+1][j+1]);
            }
        }
        return res;
    }
Solution 2. Another boring solution.
    vector<vector<int>> imageSmoother(vector<vector<int>>& M) {
        vector<vector<int>> res(M);
        int L = M.size();
        if(L==0) return res;        
        int W = M[0].size();
        if(W==0) return res;
        
        int s, c;
        for(int i=0;i<L;i++){
            for(int j=0;j<W;j++){
                s = 0;
                c = 0;
                for(int m=i-1;m<=i+1;m++) {
                    for(int n=j-1;n<=j+1;n++) {
                        if(m>=0 && m<L && n>=0 && n<W) {
                            s += M[m][n];
                            c++;
                        }
                    }
                }
                res[i][j] = s/c;
            }
        }
        return res;

    }

No comments:

Post a Comment