矩阵相关题型
Leetcode 73. 矩阵置零【中等】
题意理解:
将矩阵中0所在位置,行|列置换为全0
其中可以通过记录0元素所在的行、列号,来标记要置换的行|列
将对应位置置换为0
解题思路:
第一个思路:
可以通过两个set: row col 分别用来记录要置换的行|列号
同时set实现去重,不用重复操作
遍历row和col,将要置换的行|列,置换为全0
第二个思路:不适用额外的空间存储,使用矩阵的第一行和第一列进行存储。
1.flag_row 和flag_col标记原来的第一行|第一列是否有0,有为true
2.遍历元素(i=1,j=1),当且仅当,当前元素为0是,将对应第一行第一列的位置元素置为0
3.遍历元素(i=1,j=1),当且仅当,对应行|列头为0时,当前元素为0
4.处理第一行|第一列,当且仅当flag_row (flag_col)==true时,将第一行(第一列)置换为全0.
1.解题【额外的空间记录】
class Solution {public void setZeroes(int[][] matrix) {Set<Integer> row=new HashSet<>();Set<Integer> col=new HashSet<>();for(int i=0;i<matrix.length;i++){for(int j=0;j<matrix[0].length;j++){if(matrix[i][j]==0){row.add(i);col.add(j);}}}//填充0for(int num:row){for(int j=0;j<matrix[0].length;j++){matrix[num][j]=0;}}for(int num:col){for(int i=0;i<matrix.length;i++){matrix[i][num]=0;}}}
}
1.解题【矩阵本身记录】
class Solution {public void setZeroes(int[][] matrix) {int row=matrix.length;int col=matrix[0].length;boolean flag_row=false,flag_col=false;for(int j=0;j<col;j++){if(matrix[0][j]==0){flag_row=true;break;}}for(int i=0;i<row;i++){if(matrix[i][0]==0){flag_col=true;break;}}//记录for(int i=1;i<row;i++){for(int j=1;j<col;j++){if(matrix[i][j]==0){matrix[i][0]=0;matrix[0][j]=0;}}}//置为0for(int i=1;i<row;i++){for(int j=1;j<col;j++){if(matrix[i][0]==0||matrix[0][j]==0){matrix[i][j]=0;}}}//第一行if(flag_row){for(int j=0;j<col;j++){matrix[0][j]=0;}}//第一列if(flag_col){for(int i=0;i<row;i++){matrix[i][0]=0;}}}
}
2.复杂度分析
时间复杂度:O(n^2) 双for的时间损耗
空间复杂度:O(n) row和col的空间损耗
思路二的时间复杂度:O(1) 除了i,j外没有额外的空间损耗
Leetcode 54. 螺旋矩阵【中等】
题意理解:
从(0,0)位置顺时针螺旋,遍历数据
解题思路:
模拟转向:
1.模拟螺旋结构进行顺时针转向,其转向总是右下左上,依次循环
2.我们用directions={右、下、左、上}模拟转向,其中(i+1)%4表示选择的转向
3.转向的条件:i,j越界,或,下一个位置已经被访问过。
1.解题【模拟螺旋转向】
class Solution {public List<Integer> spiralOrder(int[][] matrix) {int row=matrix.length;int col=matrix[0].length;List<Integer> result=new ArrayList<>();if(matrix==null||matrix.length==0||matrix[0].length==0){return result;}int[][] diresction=new int[][]{{0,1},{1,0},{0,-1},{-1,0}};//右下左上boolean[][] visited = new boolean[row][col];int i_index=0,j_index=0;int direct_index=0;for(int i=1;i<=row*col;i++){result.add(matrix[i_index][j_index]);visited[i_index][j_index]=true;int nextRow=i_index+diresction[direct_index][0],nextCol=j_index+diresction[direct_index][1];//越界转向if(nextRow<0||nextRow>=row||nextCol<0||nextCol>=col||visited[nextRow][nextCol]){direct_index=(direct_index+1)%4;}i_index+=diresction[direct_index][0];j_index+=diresction[direct_index][1];}return result;}
}
1.解题【按层模拟,一次遍历转一周】
class Solution {public List<Integer> spiralOrder(int[][] matrix) {int row=matrix.length;int col=matrix[0].length;List<Integer> result=new ArrayList<>();if(matrix==null||matrix.length==0||matrix[0].length==0){return result;}//上下左右四个边界int top=0,bottom=row-1,left=0,right=col-1;while(left<=right&&top<=bottom){//左for(int j=left;j<=right;j++){result.add(matrix[top][j]);}//下for(int i=top+1;i<=bottom;i++){result.add(matrix[i][right]);}if(left<right&&top<bottom){//右for(int j=right-1;j>left;j--){result.add(matrix[bottom][j]);}//上for(int i=bottom;i>top;i--){result.add(matrix[i][left]);}}left++;right--;top++;bottom--;}return result;}
}
2.复杂度分析
思路一:
时间复杂度:O(n) for循环时间损耗
空间复杂度:O(n^2) visited[][]数组的空间损耗
思路二:
时间复杂度:O(n^2) while+for时间损耗
空间复杂度:O(n) 结果集的空间损耗