在刷题的过程中,积累了矩阵的一些常见的操作,这里特点做一下笔记,以供后续进阶学习。
1. 基本操作
1.1 沿主对角线翻转方阵
代码实现:
public void rotate(int[][] matrix) {
// 1. 临界条件
if(matrix == null || matrix.length == 0) return;
// 注意:方阵的行==列
int rows = matrix.length;
// 2. 核心逻辑
for(int i = 0; i < rows; i++) {
for(int j = i ; j < rows; j++){
int tmp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = tmp;
}
}
}
1.2 原地沿副对角线翻转方阵
代码实现:
public void rotate(int[][] matrix) {
// 1. 临界条件
if(matrix == null || matrix.length == 0) return;
// 注意:方阵的行==列
int rows = matrix.length;
// 2. 核心逻辑
for(int i = 0; i < rows; i++) {
// 和主对角线的差别在于这里。
for(int j = 0 ; j < rows - i; j++){
int tmp = matrix[i][j];
matrix[i][j] = matrix[rows-1 - j][rows-1 - i];
matrix[rows - 1 - j][rows - 1 - i] = tmp;
}
}
}
1.3 沿竖直线翻转方阵
public void rotate(int[][] matrix) {
// 1. 临界条件
if(matrix == null || matrix.length == 0) return;
// 注意:方阵的行==列
int rows = matrix.length;
// 2. 核心逻辑:对每一层都进行翻转。
for(int i = 0; i < rows; i++) {
int left =0;
int right = rows - 1;
while(left < right) {
int tmp = matrix[left][right];
matrix[left][right] = matrix[right][left];
matrix[right][left] = tmp;
}
}
}
2 . 进阶
经常刷题的同学可能都会注意到,所谓的中等难度(Medium) 和 困难难度(Hard) 很多都是将N个(N>1)基本技巧集中到一道题中。(PS: 这里不去吐槽 Leetcode的难度系数说明多么的“科学”)
上面的图对应的就是 48. 旋转图像 - M
2.1 思路1
大家可以观察上面的三张图,解题的思路都在这里面啦。
实现1:
先正对角线翻转,再竖直线翻转;
public void rotate(int[][] matrix) {
int rows = matrix.length;
int n = matrix.length;
//1. 先沿正对角线翻转
for(int i = 0;i < n;i ++)
for(int j = 0;j < i;j ++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
// 2. 沿竖直线翻转
for(int i = 0; i < rows; i++){
int left = 0;
int right = rows-1;
while(left < right){
int tmp = matrix[i][left];
matrix[i][left] = matrix[i][right];
matrix[i][right] = tmp;
left ++;
right --;
}
}
}
实现2:
先竖直线翻转,再副对角线翻转;
扫描二维码关注公众号,回复: 14747920 查看本文章
public void rotate(int[][] matrix) {
if(matrix == null || matrix.length == 0){
return ;
}
int rows = matrix.length;
// 1. 竖直线翻转
for( int i = 0; i < rows; i++){
int left = 0;
int right = rows- 1;
while(left < right){
int tmp = matrix[i][left];
matrix[i][left] = matrix[i][right];
matrix[i][right] = tmp;
left++;
right--;
}
}
// 2. 副对角线翻转
for(int i = 0 ; i < rows; i++){
for(int j = 0; j < rows - i; j++){
int tmp = matrix[i][j];
matrix[i][j] = matrix[rows-1-j][rows-1-i];
matrix[rows-1-j][rows-1-i] = tmp;
}
}
}
2.2 思路2
思路:
每个i表示一个圈,不论len是奇是偶都是一共有len/2个圈要进行旋转,从外圈向内依次旋转,直到中心点或者最内圈
public void rotate(int[][] matrix) {
int len = matrix.length;
// i 代表圈次,一共要进行 len /2 的旋转。
for (int i = 0; i < len / 2; i++) {
int start = i;
int end = len - i - 1;
for (int j = 0; j < end - start; j++) {
int temp = matrix[start][start + j];
matrix[start][start + j] = matrix[end - j][start];
matrix[end - j][start] = matrix[end][end - j];
matrix[end][end - j] = matrix[start + j][end];
matrix[start + j][end] = temp;
}
}
}