661.图片平滑器
题目:[https://leetcode-cn.com/problems/image-smoother/description/]
思路:一道直接模拟题目,计算图片的灰度,注意边界控制。
代码:
class Solution {
public:
int step(int x,int y,string &where,vector<vector<int>> &map){//走路模拟
if (where=="w") {
++x;
}
if (where=="s") {
--x;
}
if (where=="d") {
++y;
}
if (where=="a") {
--y;
}
if (where=="wa") {
++x;--y;
}
if (where=="wd") {
++x;++y;
}
if (where=="sa") {
--x;--y;
}
if (where=="sd") {
--x;++y;
}
if (where=="stop") {
return map[x][y];
}
if (x>=0&&x<map.size()&&y>=0&&y<map[0].size()) {//移动合法
return map[x][y];
}
return -1;
}
int avg_grayscale(int i,int j,vector<vector<int>> &map){//计算平均灰度
vector<string> go{"w","s","a","d","wa","wd","sd","sa","stop"};//方向控制
int sum=0,time=0,temp=0;
for (string &v:go) {
temp=step(i, j, v,map);
if (temp!=-1) {
sum+=temp;
++time;
}
}
return sum/time;
}
vector<vector<int>> imageSmoother(vector<vector<int>>& M) {
int row_max=M.size(),col_max=M[0].size();
vector<int> line(col_max);//初始化行
vector<vector<int>> ans(row_max,line);//由line初始化矩阵
for (int i=0; i!=row_max; ++i) {//第i行(i纵向)
for (int j=0;j!= col_max; ++j) {//第i行第j列(j横向)
ans[i][j]=avg_grayscale(i, j, M);
}
}
return ans;
}
};
讨论区[https://leetcode.com/problems/image-smoother/discuss/]
反思:1、多维情况一定要对每个维度对范围熟悉,避免越界产生未定义行为
2、讨论区:可以考虑由于数值只用到0~255即是8位二进制,可以考虑利用原位置中未利用对空间上进行优化,讨论区代码如下
vector<vector<int>> imageSmoother(vector<vector<int>>& M) {
int m = M.size(), n = M[0].size();
if (m == 0 || n == 0) return {{}};
vector<vector<int>> dirs = {{0,1},{0,-1},{1,0},{-1,0},{-1,-1},{1,1},{-1,1},{1,-1}}//方向数组
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int sum = M[i][j], cnt = 1;
for (int k = 0; k < dirs.size(); k++) {
int x = i + dirs[k][0], y = j + dirs[k][1];
if (x < 0 || x > m - 1 || y < 0 || y > n - 1) continue;//越界判定
sum += (M[x][y] & 0xFF);//&运算取后8位,中间8位用来保存平均值
cnt++;
}
M[i][j] |= ((sum / cnt) << 8);//与运算形成平均值(8位)+原始值(8位)的结构
}
}
for (int i = 0; i < m; i++) {//遍历数组,输出中8位平均值
for (int j = 0; j < n; j++) {
M[i][j] >>= 8;
}
}
return M;
}
3、方向数组能极好对简化代码,增加可读性和结构