Leetcode48. Rotate Image

开始没有思路,然后手推了3*3矩阵的这个rotate操作的一轮后发现,这是个循环(递归)的重复过程。

以5*5矩阵为例,第一轮我们rotate的应该是最外面一圈的16个元素,而这16个元素的顺时针旋转90度其实就是四组元素,比如第一组应为{00,04,44,40}的交换,第二组则是{01,14,43,30}的交换,抽象成数学公式的话:

$rotate[i,j]=nums[len-1-j,i]$

每轮往里走可以看为,沿着对角线往右下角找每轮的第一个元素a。每轮中下一组的第一个元素则为a右边的那个元素。

轮次level和数组长度len的关系:

每个内循环循环次数 len=5 len=6
level=0 4 5
level=1 2 3
level=2 return 1

抽象成数学公式:

$内循环次数=(len-1)-2*level$

然后就开始写啦,最近DFS(backtracking)写多了…本来应该循环就完事儿的写成了递归,一会儿再改成循环吧:

class Solution {
    public int[][] rotate(int[][] matrix) {
        helper(matrix,0);
        return matrix;
    }
    private void helper(int[][] matrix,int level){
        int len = matrix.length;
        if(2*(level+1)>len) return;
        for(int i=0;i<((len-1)-2*(level));i++){
            int p1=level,p2=level+i;
            int temp = matrix[p1][p2];
            for(int j=0;j<4;j++){
                if(j<3){
                    matrix[p1][p2]=matrix[len-1-p2][p1];
                    int tempp=p1;
                    p1=len-1-p2;
                    p2=tempp;
                }
                else
                    matrix[p1][p2]=temp;
            }
        }
        helper(matrix,level+1);
    }
}

2ms,39.08%.

 

class Solution {
    public int[][] rotate(int[][] matrix) {
        int len = matrix.length;
        if(len<=1) return matrix;
        for(int level=0;2*(level+1)<=len;level++){
            for(int i=0;i<((len-1)-2*(level));i++){
                int p1=level,p2=level+i;
                int temp = matrix[p1][p2];
                for(int j=0;j<4;j++){
                    if(j<3){
                        matrix[p1][p2]=matrix[len-1-p2][p1];
                        int tempp=p1;
                        p1=len-1-p2;
                        p2=tempp;
                    }
                    else
                        matrix[p1][p2]=temp;
                }
            }
        }
        return matrix;
    }
}

还是2ms。看看1ms答案。

思路一样,只不过把内循环直接展开了,所以个人最优解即可。

posted @ 2019-01-01 21:37  大胖子球花  阅读(95)  评论(0)    收藏  举报