• 48. Rotate Image


    题目:

    You are given an n x n 2D matrix representing an image.

    Rotate the image by 90 degrees (clockwise).

    Follow up:
    Could you do this in-place?

    链接:  http://leetcode.com/problems/rotate-image/

    题解:

    in-place,按照顺时针移动整个矩阵的1/4,注意边长为奇数时的corner case。 还有方法是对折再变换的。

    Time complexity - O(n2), Space Complexity - O(1)

    public class Solution {
        public void rotate(int[][] matrix) {
            if(matrix == null || matrix.length == 0)
                return;
            int n = matrix.length - 1;
            
            for(int i = 0; i <= n / 2; i++) {
                for(int j = 0; j < (n + 1) / 2; j++) {
                    int tmp = matrix[i][j];
                    matrix[i][j] = matrix[n - j][i];
                    matrix[n - j][i] = matrix[n - i][n - j];
                    matrix[n - i][n - j] = matrix[j][n - i];
                    matrix[j][n - i] = tmp;
                }
            }
        }
    }

    Follow up是对矩阵最外部的元素,每个元素向右移动一个位置。可能药用spiral matrix一类的方法。

    再Follow up可以 design一个三消游戏,类似 Candy Crush saga。

    二刷:

    这里看漏了n x n matrix,其实m = n就可以了。注意遍历的边界条件, i 可以 < n /2, 这样j就必须要 j < (n + 1) / 2来cover中间的奇数元素。还可以想得再透彻一些。还有不少大神有很好的翻转方法,先记录在reference里,留给三刷了。

    Java:

    Time complexity - O(n2), Space Complexity - O(1)

    public class Solution {
        public void rotate(int[][] matrix) {
            if (matrix == null || matrix.length == 0) {
                return;
            }
            int m = matrix.length, n = matrix[0].length;
            for (int i = 0; i < m / 2; i++) {
                for (int j = 0; j < (n + 1) / 2; j++) {
                    int tmp = matrix[i][j];
                    matrix[i][j] = matrix[m - 1 - j][i];
                    matrix[m - 1 - j][i] = matrix[m - 1 - i][n - 1 - j];
                    matrix[m - 1 - i][n - 1 - j] = matrix[j][n - 1 - i];
                    matrix[j][n - 1 - i] = tmp;
                }
            }
        }
    }

    同时也做了一下 Rotate Matrix by 1, 发了一篇新文

    Rotate Matrix by One 

    题外话:

    1/27/2016

    今天群里讨论interval search tree,很精彩。我打算好好复习一下相关的知识。昨天讨论Google面试题密码箱问题,de brujin, hamiton path和 euler path,还是要好好向dietpepsi大神学习。 要扎实,反应敏捷并且准确,还要能迅速写出代码才能。现在差得还很远。

    三刷:

    这里的边界条件要注意一下。因为题目给出m = n,所以input是边长都是n的方阵。 我们旋转的方阵分为两种,一种是边长为奇数的,一种是边长为偶数的。

    旋转边长为偶数的矩阵时,我们要根据  len / 2 把矩阵分为四个部分,只需要旋转左上部分就行了,比如n = 4,那么我们的条件就是 i < 2和 j < 2。  

    [1, 2, 3, 4]

    [5, 6, 7, 8]

    [1, 2, 3, 4]

    [5, 6, 7, 8]

    另外一种是奇数边长的矩阵,这时候我们旋转的也是左上部分,不过左上部分这时候不是一个方阵,而是一个类似于三角形,或者梯形的区域。比如下图,这里其实我们要旋转的是1和2,或者1和4。假如我们同时旋转1, 2和4, 那么就会出现重复步骤造成结果不正确。

    所以这时候我们对边长的界定应该是,  i < (len + 1) / 2, 即对row 添加1然后除以2,转换成偶数边长时遍历的情况, 而 j < len / 2, 对j来说不变,还是维持奇数边长时遍历的情况。当然这里我们也可以互换i 和 j。 这样处理就保证了我们在操作的时候没有多余步骤。

    [1, 2, 3]

    [4, 5, 6]

    [7, 8, 9]

    Java:

    public class Solution {
        public void rotate(int[][] matrix) {
            if (matrix == null) return;
            int len = matrix.length;
            for (int i = 0; i < (len + 1) / 2; i++) {
                for (int j = 0; j < len / 2; j++) {
                    int tmp = matrix[i][j];
                    matrix[i][j] = matrix[len - 1 - j][i];
                    matrix[len - 1 - j][i] = matrix[len - 1 - i][len - 1 - j];
                    matrix[len - 1 - i][len - 1 - j] = matrix[j][len - 1 - i];
                    matrix[j][len - 1 - i] = tmp;
                }
            }
        }
    }

    Reference:

    https://leetcode.com/discuss/20589/a-common-method-to-rotate-the-image

    https://leetcode.com/discuss/38426/seven-short-solutions-1-to-7-lines

    https://leetcode.com/discuss/27262/java-in-place-solution-with-explanation-easy-to-understand

  • 相关阅读:
    信息安全系统设计与实现学习笔记1
    信息安全系统设计与实现学习笔记2
    《信息安全系统设计与实现学习笔记3》
    信息安全系统设计与实现学习笔记4
    SAP PP——常用函数
    ReentrantLock
    WPS图片工具 MrFlySand
    【记者团】团队合作 MrFlySand
    华为HCDA论证教程 MrFlySand
    Windowd server2016教程(详细) MrFlySand
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4436352.html
Copyright © 2020-2023  润新知