> 文档中心 > 【学习报告】《LeetCode零基础指南》(第八讲) 二级指针

【学习报告】《LeetCode零基础指南》(第八讲) 二级指针

目录

一、练习题目

832. 翻转图像

867. 转置矩阵

566. 重塑矩阵

2022. 将一维数组转变成二维数组

1260. 二维网格迁移

661. 图片平滑器

1314. 矩阵区域和

1030. 距离顺序排列矩阵单元格

二、答题总结


一、练习题目

832. 翻转图像

给定一个 n x n 的二进制矩阵 image ,先 水平 翻转图像,然后 反转 图像并返回 结果 。

水平翻转图片就是将图片的每一行都进行翻转,即逆序。

例如,水平翻转 [1,1,0] 的结果是 [0,1,1]。
反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。

例如,反转 [0,1,1] 的结果是 [1,0,0]。

示例 1:

输入:image = [[1,1,0],[1,0,1],[0,0,0]]
输出:[[1,0,0],[0,1,0],[1,1,1]]
解释:首先翻转每一行: [[0,1,1],[1,0,1],[0,0,0]];
     然后反转图片: [[1,0,0],[0,1,0],[1,1,1]]
示例 2:

输入:image = [[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]]
输出:[[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]
解释:首先翻转每一行: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]];
     然后反转图片: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]

class Solution {    public int[][] flipAndInvertImage(int[][] image) { int n=image.length; int m=image[0].length; int[][] arr=new int[n][m]; for(int i=0;i<n;i++){     for(int j=0;j<m;j++){  arr[i][m-j-1]=image[i][j];     } } for(int i=0;i<n;i++){     for(int j=0;j<m;j++){  if(arr[i][j]==1){      arr[i][j]=0;  }else{      arr[i][j]=1;  }     } } return arr;    }}

867. 转置矩阵

给你一个二维整数数组 matrix, 返回 matrix 的 转置矩阵 。

矩阵的 转置 是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[1,4,7],[2,5,8],[3,6,9]]
示例 2:

输入:matrix = [[1,2,3],[4,5,6]]
输出:[[1,4],[2,5],[3,6]]

class Solution {    public int[][] transpose(int[][] matrix) { int m = matrix.length; int n = matrix[0].length; int[][] res = new int[n][m]; for (int i = 0; i < m; i++) {     for (int j = 0; j < n; j++) {  res[j][i] = matrix[i][j];     } }    return res;    }}

566. 重塑矩阵

在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。

给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。

重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。

如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

示例 1:
输入:mat = [[1,2],[3,4]], r = 1, c = 4
输出:[[1,2,3,4]]
示例 2:
输入:mat = [[1,2],[3,4]], r = 2, c = 4
输出:[[1,2],[3,4]]

class Solution {    public int[][] matrixReshape(int[][] mat, int r, int c) { int m = mat.length, n = mat[0].length; // 特殊情况判断  if (m * n != r * c) {     return mat; } // 双重循环 + 数组元素位置 // 例:原5*7数组中的一个元素a[2][4],要放在新的7*5数组的什么位置?? // a[2][4] = 2 * 7 + 4 = 18 // 按行遍历的话 // 所以他应该在新数组的中得位置:b[18 / 5]][18 % 5] = b[3][3] => 3*5+3=18 int[][] arr = new int[r][c]; int count = 0;// 表示按行遍历时,在数组中的第几个位置 for (int i = 0; i < r; i++) {     for (int j = 0; j < c; j++) {  arr[i][j] = mat[count / n][count % n];  count++;     } } return arr;    }}
  • 这个题看的题解,还没有看懂,备注一下,有时间回来再看看。

2022. 将一维数组转变成二维数组

给你一个下标从 0 开始的一维整数数组 original 和两个整数 m 和  n 。你需要使用 original 中 所有 元素创建一个 m 行 n 列的二维数组。

original 中下标从 0 到 n - 1 (都 包含 )的元素构成二维数组的第一行,下标从 n 到 2 * n - 1 (都 包含 )的元素构成二维数组的第二行,依此类推。

请你根据上述过程返回一个 m x n 的二维数组。如果无法构成这样的二维数组,请你返回一个空的二维数组。

示例 1:
输入:original = [1,2,3,4], m = 2, n = 2
输出:[[1,2],[3,4]]
解释:
构造出的二维数组应该包含 2 行 2 列。
original 中第一个 n=2 的部分为 [1,2] ,构成二维数组的第一行。
original 中第二个 n=2 的部分为 [3,4] ,构成二维数组的第二行。
示例 2:

输入:original = [1,2,3], m = 1, n = 3
输出:[[1,2,3]]
解释:
构造出的二维数组应该包含 1 行 3 列。
将 original 中所有三个元素放入第一行中,构成要求的二维数组。
示例 3:

输入:original = [1,2], m = 1, n = 1
输出:[]
解释:
original 中有 2 个元素。
无法将 2 个元素放入到一个 1x1 的二维数组中,所以返回一个空的二维数组。
示例 4:

输入:original = [3], m = 1, n = 2
输出:[]
解释:
original 中只有 1 个元素。
无法将 1 个元素放满一个 1x2 的二维数组,所以返回一个空的二维数组。

class Solution {    public int[][] construct2DArray(int[] original, int m, int n) { int num=original.length; int k=0; int[][] arr=new int[m][n]; if((m*n)==num){     for(int i=0;i<m;i++){  for(int j=0;j<n;j++){      arr[i][j]=original[k];      k++;  }     }     return arr; } return new int[][]{};    }}

1260. 二维网格迁移

给你一个 m 行 n 列的二维网格 grid 和一个整数 k。你需要将 grid 迁移 k 次。

每次「迁移」操作将会引发下述活动:

位于 grid[i][j] 的元素将会移动到 grid[i][j + 1]。
位于 grid[i][n - 1] 的元素将会移动到 grid[i + 1][0]。
位于 grid[m - 1][n - 1] 的元素将会移动到 grid[0][0]。
请你返回 k 次迁移操作后最终得到的 二维网格。

示例 1:

输入:grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1
输出:[[9,1,2],[3,4,5],[6,7,8]]
示例 2:

输入:grid = [[3,8,1,9],[19,7,2,5],[4,6,11,10],[12,0,21,13]], k = 4
输出:[[12,0,21,13],[3,8,1,9],[19,7,2,5],[4,6,11,10]]
示例 3:

输入:grid = [[1,2,3],[4,5,6],[7,8,9]], k = 9
输出:[[1,2,3],[4,5,6],[7,8,9]]

class Solution {    public List<List> shiftGrid(int[][] grid, int k) { List<List> ans = new ArrayList<List>(); int n = grid.length; int m = grid[0].length; k = k % (n * m); int begin = n * m - k; for (int i = 0; i < n; i++) {     List tmp = new ArrayList();     for (int j = 0; j < m; j++) {  int now = (begin + i * m + j) % (n * m);  int value = grid[now / m][now % m];  tmp.add(value);     }     ans.add(tmp); } return ans;    }}

661. 图片平滑器

图像平滑器 是大小为 3 x 3 的过滤器,用于对图像的每个单元格平滑处理,平滑处理后单元格的值为该单元格的平均灰度。

每个单元格的  平均灰度 定义为:该单元格自身及其周围的 8 个单元格的平均值,结果需向下取整。(即,需要计算蓝色平滑器中 9 个单元格的平均值)。

如果一个单元格周围存在单元格缺失的情况,则计算平均灰度时不考虑缺失的单元格(即,需要计算红色平滑器中 4 个单元格的平均值)。

给你一个表示图像灰度的 m x n 整数矩阵 img ,返回对图像的每个单元格平滑处理后的图像 。

示例 1:

输入:img = [[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
示例 2:
输入: img = [[100,200,100],[200,50,200],[100,200,100]]
输出: [[137,141,137],[141,138,141],[137,141,137]]
解释:
对于点 (0,0), (0,2), (2,0), (2,2): floor((100+200+200+50)/4) = floor(137.5) = 137
对于点 (0,1), (1,0), (1,2), (2,1): floor((200+200+50+200+100+100)/6) = floor(141.666667) = 141
对于点 (1,1): floor((50+200+200+200+200+100+100+100+100)/9) = floor(138.888889) = 138

class Solution {    public int[][] imageSmoother(int[][] img) { int R = img.length, C = img[0].length; int[][] ans = new int[R][C]; for (int r = 0; r < R; ++r)   //原数组行遍历     for (int c = 0; c < C; ++c) {    //原数组列遍历  int count = 0; //存下周围数的个数  for (int nr = r-1; nr <= r+1; ++nr)  //遍历r的上下      for (int nc = c-1; nc <= c+1; ++nc) {   //遍历c的左右   if (0 <= nr && nr < R && 0 <= nc && nc < C) {   //判断边界ans[r][c] += img[nr][nc];  //将周围数相加count++;   //周围有几个个数   }      }  ans[r][c] /= count;  //求平均值     } return ans;    }}

1314. 矩阵区域和

给你一个 m x n 的矩阵 mat 和一个整数 k ,请你返回一个矩阵 answer ,其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和: 

i - k <= r <= i + k,
j - k <= c <= j + k 且
(r, c) 在矩阵内。

示例 1:

输入:mat = [[1,2,3],[4,5,6],[7,8,9]], k = 1
输出:[[12,21,16],[27,45,33],[24,39,28]]
示例 2:

输入:mat = [[1,2,3],[4,5,6],[7,8,9]], k = 2
输出:[[45,45,45],[45,45,45],[45,45,45]]

class Solution {    public int[][] matrixBlockSum(int[][] mat, int k) { int n=mat.length; int m=mat[0].length; int[][] arr=new int[n][m]; for(int i=0;i<n;i++){     for(int j=0;j<m;j++){  for(int k1=i-k;k1<=i+k;k1++){      for(int l=j-k;l<=j+k;l++){   if(k1=0 && l=0){arr[i][j]+=mat[k1][l];   }      }  }     } } return arr;    }}

1030. 距离顺序排列矩阵单元格

给定四个整数 row ,   cols ,  rCenter 和 cCenter 。有一个 rows x cols 的矩阵,你在单元格上的坐标是 (rCenter, cCenter) 。

返回矩阵中的所有单元格的坐标,并按与 (rCenter, cCenter) 的 距离 从最小到最大的顺序排。你可以按 任何 满足此条件的顺序返回答案。

单元格(r1, c1) 和 (r2, c2) 之间的距离为|r1 - r2| + |c1 - c2|。

示例 1:

输入:rows = 1, cols = 2, rCenter = 0, cCenter = 0
输出:[[0,0],[0,1]]
解释:从 (r0, c0) 到其他单元格的距离为:[0,1]
示例 2:

输入:rows = 2, cols = 2, rCenter = 0, cCenter = 1
输出:[[0,1],[0,0],[1,1],[1,0]]
解释:从 (r0, c0) 到其他单元格的距离为:[0,1,1,2]
[[0,1],[1,1],[0,0],[1,0]] 也会被视作正确答案。
示例 3:

输入:rows = 2, cols = 3, rCenter = 1, cCenter = 2
输出:[[1,2],[0,2],[1,1],[0,1],[1,0],[0,0]]
解释:从 (r0, c0) 到其他单元格的距离为:[0,1,1,2,2,3]
其他满足题目要求的答案也会被视为正确,例如 [[1,2],[1,1],[0,2],[1,0],[0,1],[0,0]]。

class Solution {    public int[][] allCellsDistOrder(int R, int C, int r0, int c0) { // 找到最大可达的距离。 int maxDist = Math.max(r0, R-1-r0) + Math.max(c0, C-1-c0); // 创建桶 List<List> bucket = new ArrayList<List>(); // 赋给桶的大小,最大为距离最大,距离一样的放在一个桶。 for(int i=0; i<=maxDist; i++){     bucket.add(new ArrayList()); } //调用方法计算出距离,然后把坐标放在对应的桶中。 for(int i=0; i<R; i++){     for(int j=0; j<C; j++){  int d = dist(i, j, r0, c0);  bucket.get(d).add(new int[]{i,j});     } } //创建二维数组对象 int[][] ret = new int[R*C][]; //创建指针 int index = 0; //出桶,加入二维数组中 for(int i=0; i<=maxDist; i++){     for(int j=0; j<bucket.get(i).size(); j++){  ret[index] = bucket.get(i).get(j);  index++;     } } return ret;    }    //算出距离的方法    public int dist(int r1, int c1, int r2, int c2){ return Math.abs(r1-r2)+Math.abs(c1-c2);    }}

二、答题总结

        今天的题目给我的感觉就是好难,救命,有一些思路直接想不到,还有用到的dp、dfs、bfs啥的真的不会,之前没有好好学,只会一个暴力的菜鸡在线卑微,还有机会,现在开始也不晚,奥里给!