题目
思路
将数组中的每四个位置的值看成一组,比如示例1就可以分为两组:[1, 3, 9, 7],[2, 6, 8, 4];示例2可以分为4组:[5, 11, 16, 15],[1, 10, 12, 13], [9, 7, 16, 2]和[4, 8, 6, 3],以此类推,我们可以将矩阵中所有需要相互交换位置的分为一组,然后只要找到每一组数据所在的位置,然后交换他们的位置即可;
解题方法
按照循环遍历数组的思路,每个分组的元素之间都是固定步长的距离,比如示例1:[1, 3, 9, 7]之前的步长距离为2;
我们可以从最外圈的元素开始遍历,一直到最内圈的元素,遍历得到每组数据的位置,然后交换得到最终的位置即可。
每一圈我们只需要遍历第一个元素到倒数第二个元素就可以了,刚好分为这么多组数据。
具体还是看我代码的实现,结合起来理解!
Code
class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;
// 每一轮的边界
int minLimit = -1, maxLimt = n;
// 初始位置
int row = 0, col = 0;
// 每一轮的步长
int step = maxLimt - minLimit - 2;
// 从最外围一圈开始,一直到最里面的一圈
while(row > minLimit && row < maxLimt && col > minLimit && col < maxLimt){
// 每一圈的分组都是从第一个到倒数第二个元素进行划分的
while(col < maxLimt - 1){
// 获取每一组元素的位置
int curRow1 = row, curCol1 = col;
int[] next = getNextPos(matrix, minLimit, maxLimt, curRow1, curCol1, step, 0);
int curRow2 = next[0], curCol2 = next[1];
next = getNextPos(matrix, minLimit, maxLimt, curRow2, curCol2, step, 1);
int curRow3 = next[0], curCol3 = next[1];
next = getNextPos(matrix, minLimit, maxLimt, curRow3, curCol3, step, 2);
int curRow4 = next[0], curCol4 = next[1];
// 交换位置,得到旋转的效果
swap(matrix, curRow1, curCol1, curRow2, curCol2);
swap(matrix, curRow1, curCol1, curRow4, curCol4);
swap(matrix, curRow4, curCol4, curRow3, curCol3);
col++;
}
// 更新下一圈
minLimit++;
maxLimt--;
row++;
col = row;
step = maxLimt - minLimit - 2;
}
}
public int[] getNextPos(int[][] matrix, int minLimit, int maxLimt, int row, int col, int step, int direction){
switch(direction){
// 右
case 0:
if(col + step < maxLimt){
return new int[]{row, col + step};
}else{
return new int[]{row + (step - (maxLimt - 1 - col)), maxLimt - 1};
}
// 下
case 1:
if(row + step < maxLimt){
return new int[]{row + step, col};
}else{
return new int[]{maxLimt - 1, col - (step - (maxLimt - 1 - row))};
}
// 左
case 2:
if(col - step > minLimit){
return new int[]{row, col - step};
}else{
return new int[]{row - (step - (col - minLimit - 1)), minLimit + 1};
}
// 上
case 3:
if(row - step > minLimit){
return new int[]{row - step, col};
}else{
return new int[]{minLimit + 1, col + (step - (row - minLimit - 1))};
}
}
return null;
}
public void swap(int[][] matrix, int row1, int col1, int row2, int col2){
int temp = matrix[row1][col1];
matrix[row1][col1] = matrix[row2][col2];
matrix[row2][col2] = temp;
}
}
总结
这题是没有看官方解题按自己的思路写出来的,看了其他题解没看到有跟我一样的解法,因此在这里记录一下。
我的题解思路实现起来确实比较麻烦,写的时候很多边界条件的判断差点给我绕晕了,调试了很久才写出来,但思路是最简单粗暴的,写完后感觉非常锻炼自己写代码的思维能力!