旋转图像 思路 java实现

旋转图像 思路 java实现_第1张图片
上图是题目描述来源LeetCode
我的第一种解法是 将所给二维数组由外向内分成n/2上取整层
然后逐层各元素顺时针移动90度
举个例子
旋转图像 思路 java实现_第2张图片
最外层像这样移动,那么当完成对倒数第二个元素的移动时该层的旋转也就完成了 那上面的例子来说就是在第一层完成对2的移动时就已经完成了最外层的旋转,再往里只有一个元素,不用旋转。
时间复杂度分析
(n-1)*4+(n-3)**4+…+1 = O(n^2)
算法实现

class Solution {
    public void rotate(int[][] matrix) {
        int len = matrix.length;
		for(int i = 0;;i++)
		{
			int j = i;
			int last = i+len-1;
			int start = i;
			for(;j<i+len-1;j++)
			{
				int temp = 0;
				int time = 0;
				while(time < 4)
				{
					int ai,aj;
					if(time == 0)
					{
						aj = last;
						ai = i+((j+len-1)%last);
						temp = matrix[ai][aj];
						matrix[ai][aj] = matrix[i][j];
						i = ai;
						j = aj;
						time++;
					}
					if(time == 1)
					{
						aj = j - ((i+len-1)%last);
						ai = last ;
						temp = matrix[ai][aj]^temp;
						matrix[ai][aj] = matrix[ai][aj]^temp;
						temp = matrix[ai][aj]^temp;
						i = ai;
						j = aj;
						time++;
					}
					if(time == 2)
					{
						aj = start;
						ai = j;
						temp = matrix[ai][aj]^temp;
						matrix[ai][aj] = matrix[ai][aj]^temp;
						temp = matrix[ai][aj]^temp;
						i = ai;
						j = aj;
						time++;
					}
					if(time == 3)
					{
						ai = last - len + 1;
						aj = j - ((i - len +1)-start);
						temp = matrix[ai][aj]^temp;
						matrix[ai][aj] = matrix[ai][aj]^temp;
						temp = matrix[ai][aj]^temp;;
						j = aj;
						i = ai;
						time ++;
					}
				}
			}
			len -= 2;
			if(len <= 1)
			{
				break;
			}
		}
    }
}

代码量60行左右十分复杂
另一种方法是
矩阵转置加翻转
仔细观察会发现 图像旋转顺时针旋转90度刚好是图像矩阵转置 然后各行数组倒序
代码实现

public void rotate(int[][] matrix) {
		for(int i = 0;i<matrix.length;i++)
		{
			for(int j = i+1;j<matrix.length;j++)
			{
				matrix[i][j] = matrix[i][j]^matrix[j][i];
				matrix[j][i] = matrix[i][j]^matrix[j][i];
				matrix[i][j] = matrix[i][j]^matrix[j][i];
			}
		}//矩阵转置
		
		for(int i = 0;i<matrix.length;i++)
		{
			for(int j = 0;j<matrix.length/2;j++)
			{
				matrix[i][j] = matrix[i][j]^matrix[i][matrix.length-1-j];
				matrix[i][matrix.length-1-j] = matrix[i][j]^matrix[i][matrix.length-1-j];
				matrix[i][j] = matrix[i][j]^matrix[i][matrix.length-1-j];
			}
		}//倒序
    }

时间复杂度
转置 n*(n-1)/2 = O(n^2);
翻转 O(nlog(n))
最后也就是 O(n^2)
简简单单20行
虽然时间复杂度是一样的但是 显然第二种是优解

2 tips
tip1:翻转算法 ,折半对换时间复杂度 就是将一个数组对半分,首尾相替。
tip2:两值互换,常用的是引入一个临时变量,临时存储一个元素的办法。这里用的是异或换值法,省去了临时变量,目的同样是将两值互换。
互换公式 现有两值 a ,b 欲交换a,b ;换法
a = a^b;
b = a^b;
a = a^b;

我算法入门水平,有不对的恳请指出!任何想法欢迎留言。

你可能感兴趣的:(算法)