LeetCode典型题目系列 48. Rotate Image 旋转图像

LeetCode典型题目系列 48. Rotate Image 旋转图像

  • LeetCode典型题目系列
    • 题目 48. Rotate Image
    • 思路
    • 编程技巧
    • Code (Java)
    • 易错点

LeetCode典型题目系列

作为一名学计算机的学生,之前一直少有练习OJ,写博客,维护自己的GitHub的觉悟,说到底还是太懒了。春招以来愈发觉得练习OJ的重要性,于是准备写一些博客,记录自己遇到的典型题目和思考,一方面是给自己的笔记,另一方面给大家参考。个人水平有限,如有谬误请指出,也欢迎大家的讨论。

题目 48. Rotate Image

LeetCode典型题目系列 48. Rotate Image 旋转图像_第1张图片
LeetCode典型题目系列 48. Rotate Image 旋转图像_第2张图片

题目大意是原地旋转二维矩阵,不允许创建新矩阵。

思路

这种二维矩阵的旋转是一类典型题目,写代码时有一些固定的技巧可以使用。

对于给定的 n * n的方阵,从最外层开始处理,每次处理一层,处理完了外层再向里面一层推进,直到未处理的矩阵的size为 0 * 0 或者 1 * 1 结束。

每一层处理的时候可以按照顺时针(本题是按照顺时针旋转)进行。每一层可以看做4组list,以下图为例,分别是黄色框框里的(1, 2)、(3, 6)、(9, 8)、(7, 4)。
每一层要做的就是将4组list里对应位置的数字按照顺时针交换一下。
LeetCode典型题目系列 48. Rotate Image 旋转图像_第3张图片

编程技巧

这类二维矩阵的题目可以用TR表示top row(第一行), TC表示top col(第一列)。同理还有DR,DC。使用这样4个index两两组合,加上offset(偏移量),就可以比较清晰地在矩阵中找到相关数字,具体逻辑请看code:

Code (Java)

// Java code
class Solution {
    public void rotate(int[][] matrix) {
        helper(matrix, 0, 0, matrix.length - 1, matrix[0].length - 1);
    }
    
    public void helper(int[][] matrix, int TR, int TC, int DR, int DC) {
    	// 递归终止条件
        if(TR >= DR) {
            return;
        }
        
        // 4个index表示了最外层,循环里的5步是对最外层4个list对应位置元素的交换,i表示offset
        for(int i = 0; i < DC - TC; i++) {
            int tmp = matrix[TR][TC + i];
            matrix[TR][TC + i] = matrix[DR - i][TC];
            matrix[DR - i][TC] = matrix[DR][DC - i];
            matrix[DR][DC - i] = matrix[TR + i][DC];
            matrix[TR + i][DC] = tmp;
        }
        helper(matrix, TR + 1, TC + 1, DR - 1, DC - 1);
    }
}

易错点

注意offset的范围:每一圈交换的list长度并没有达到一行或一列的长度(方阵的大小n),list的长度是n - 1,以example1的最外圈为例,每个list的长度是3 - 1 = 2,第一个list为(1, 2),DC的值(3)是取不到的,因此每一圈中也可以把list的长度看成DC - TC。
而list中offset是从0开始计算的, 因此offset的最大值是DC - TC - 1。

你可能感兴趣的:(LeetCode)