矩阵相关题型
Leetcode 48. 旋转图像【中等】
题意理解:
将一个矩阵顺时针旋转90度,返回旋转后的矩阵。
要求: 在原地修改,不借助额外的空间
如果可以使用辅助数组来实现转置,则有
matrix_new[i][j]=matrix[j][row-i-1];
解题思路:
(1) 四数循环:
将其一层一层的进行转置
首先看最外面的一层,将其分为红色方框中的四部分
从第一个红色方框开始: 第一个位置(0,0)将转置到(0,2)的位置上
原本(0,2)的位置上的数转置到(2,2),
原来(2,2)上的数转置到(2,0)
原来(2,0)的位置转置到(0,0)
即: (0,0)->(0,2)->(2,2)->(2,0)->(0,2)->(0,0)
坐标变化为: (i,j)->(j,row-i-1) 变换四次
完成一个红色框的所有元素的变换,则完成了一层数据的转置
如何进入下一层呢?
i++,j++即可,重复上述操作。
何时跳出循环:
当且仅当,i,j指向中心元素时,跳出循环,如下图中: i=3/2=1 时,走到矩阵核心,不需要继续转置
能不能理解更简单一些呢?
对于四数循环的while可以从循环中展开:即实现四数互换
思路二:反转替代转置
顺时针转置90度=水平+对角线
水平翻转: new_i,new_j=row-i-1,j
对角线反转: new_i,new_j=j,i
1.解题【四数循环】
class Solution {public void rotate(int[][] matrix) {//使用坐标变换的逻辑,实现旋转int row=matrix.length,col=matrix[0].length;int cur_i=0,cur_j=0;int curVal=matrix[cur_i][cur_j];while(cur_i!=row/2){for(int j=cur_i;j<row-cur_i-1;j++){cur_j=j;curVal=matrix[cur_i][cur_j];int count=4;while(count-->0){int next_i=cur_j;int next_j=row-cur_i-1;int nextVal=matrix[next_i][next_j];matrix[next_i][next_j]=curVal;cur_i=next_i;cur_j=next_j;curVal=nextVal;}}cur_i++;}}
}
改进:可以将四数循环的while展开写:
class Solution {public void rotate(int[][] matrix) {//使用坐标变换的逻辑,实现旋转int row=matrix.length,col=matrix[0].length;int cur_i=0;while(cur_i!=row/2){for(int cur_j=cur_i;cur_j<row-cur_i-1;cur_j++){int temp=matrix[cur_i][cur_j];matrix[cur_i][cur_j]=matrix[row-cur_j-1][cur_i];matrix[row-cur_j-1][cur_i]=matrix[row-cur_i-1][row-cur_j-1];matrix[row-cur_i-1][row-cur_j-1]=matrix[cur_j][row-cur_i-1];matrix[cur_j][row-cur_i-1]=temp;System.out.println( matrix[cur_i][cur_j]+" "+matrix[row-cur_i-1][cur_j]+" "+matrix[row-cur_i-1][row-cur_j-1]+" "+matrix[cur_i][row-cur_j-1]);}cur_i++;}}
}
1.翻转替代转置【水平翻转+对角线翻转】
class Solution {public void rotate(int[][] matrix) {//使用坐标变换的逻辑,实现旋转int row=matrix.length,col=matrix[0].length;//水平翻转for(int i=0;i<row/2;i++){for(int j=0;j<col;j++){int temp=matrix[i][j];matrix[i][j]=matrix[row-i-1][j];matrix[row-i-1][j]=temp;}}//对角线翻转for(int i=0;i<row;i++){for(int j=0;j<i;j++){int temp=matrix[i][j];matrix[i][j]=matrix[j][i];matrix[j][i]=temp;}}}
}
2.复杂度分析
时间复杂度:O(n^2) while(n/2)+for循环+4次while循环的时间损耗
空间复杂度:O(1) 原地转置的空间损耗
Leetcode 240. 搜索二维矩阵 II【中等】
题意理解:
这个矩阵是有顺序的,左到右升序,上到下升序
要求找到执行的元素,找到为true,否则为false
解题思路:
1.逐个对比:双for循环
2.由于每行都是升序,可以对于每行进行二分排序
3.对角线查找:每行都是顺序升序的,每列也是升序的
从右上角到左下角,比当前值大往左,比当前值小往下
上下维度控制变大,左右维度控制变小
1.解题【双for循环】
class Solution {public boolean searchMatrix(int[][] matrix, int target) {int row=matrix.length,col=matrix[0].length;for(int i=0;i<row;i++){for(int j=0;j<col;j++){if(matrix[i][j]==target) return true;}}return false;}
}
1.解题:【遍历行二分查】
class Solution {public boolean searchMatrix(int[][] matrix, int target) {int row=matrix.length,col=matrix[0].length;for(int i=0;i<row;i++){//对每行进行二分查找int low=0,high=col-1;while(low<=high){int mid=(high-low)/2+low;int midNum=matrix[i][mid];if(midNum==target) return true;else if(midNum>target){high=mid-1;}else{low=mid+1;}}}return false;}
}
1.解题:【对角线查找】
class Solution {public boolean searchMatrix(int[][] matrix, int target) {int row=matrix.length,col=matrix[0].length;int i=0,j=col-1;//从右上角往左下角找,==返回>往左,<往下while(x<row&&y>=0){if(matrix[i][j]==target){return true;}else if(matrix[i][j]>target){j--;}else if(matrix[i][j]<target){i++;}}return false;}
}
2.复杂度分析
思路一:
时间复杂度:O(n^2) 双for的时间损耗
空间复杂度:O(1) 变量的空间损耗
思路二:
时间复杂度:O(nlogn) for+二分的时间损耗
空间复杂度:O(1) 变量的空间损耗
思路一:
时间复杂度:O(n) 双for的时间损耗
空间复杂度:O(1) 变量的空间损耗