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答案。
思路一样,只不过把内循环直接展开了,所以个人最优解即可。

浙公网安备 33010602011771号