算法优化:旋转对称图最优解法及思路分享(几乎最优)


前言

本文将总结并分享类似旋转图的最优算法思路及代码


一、问题描述

给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。

实例:

给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

二、算法展示

1.成果展示

代码如下(示例):

class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix[0].length;
        for(int i=0;i*2<n;i++){
            for(int j=i;j<n-i-1;j++){
                swap(matrix,i,j,n-j-1,i);    //1->4,4->1
                swap(matrix,n-j-1,i,n-i-1,n-j-1); //1->3,3->4
                swap(matrix,n-i-1,n-j-1,j,n-i-1); //1->2,2->3  
            }
              
        }
    }

    public void swap(int[][]matrix,int i1,int j1,int i2,int j2){
        int temp =matrix[i1][j1];
        matrix[i1][j1] = matrix[i2][j2];
        matrix[i2][j2] = temp; 

    }
}

2.读入数据

在这里插入图片描述

三、算法思路分析

1.切入点分析

在碰到这种题的时候估计很多人都是在想,90度旋转应该怎么通过交换实现呢?这应该建立几个for循环呢?糟糕我这算法还没实现就建立了这么多for循环了,这算法肯定扯犊子了!…。其实每个人都是这样想的,但是这样想你会发现算法题变得越加的复杂,逻辑越发的难以梳理,总结一句话就是拿到题的时候你想得太多了。拿本题来说:首先你旋转的话a[0][0] (n=4)需要移动到a[3][0]位置上,但是你若是简单交换的话,此时你会发现[0][0]的位置对了,但是30位置的值却移动到了00位置上,此时你又要考虑30位置到00位置的情况,由此顾此失彼,你会发现算法越来越复杂,越来越复杂,本来没那么难的问题此时将变得无比复杂。而在我看来造成这些的主要原因是你的切入点不对造成的。那什么才叫做正确的切入点呢?下面我们将慢慢讲述。

2.正确切入点

对于任何一个算法题都是由实际问题延伸而来的。因此一个复杂算法可以被切分为的两个方面处理:1.算法实现逻辑;2.算法优化策略。而算法的优化策略完全是由算法的实现逻辑决定的,因此首要切入点是算法的实现逻辑。

3.算法的实现逻辑

若想完全理解算法的实现逻辑,首先是要结合实例,不过是然后将实例抽象开,找出隐含逻辑。拿本题举例来说。
首先列举实例

array ={
	{1 ,2 ,3 ,4 },
	{5 ,6 ,7 ,8 },
	{9 ,10,11,12},
	{13,14,15,16}
}
旋转90°=>
array ={
	{13,9 ,5 ,1 },
	{14,10,6 ,2 },
	{15,11,7 ,3 },
	{16,12,8 ,4 }
}

然后对具体实例进行抽象,此时其中1->4,2->8,3->12,4->16
a[0][0]->a[0][3]、a[0][1]->a[1][3]、a[0][2]->a[2][3]、a[0][3]->a[3][3] n=4(n一行含的元素)
此时好像发现了一些规律了。然后通过再举例
找出了a[i][j]->a[j][n-j-1]。此时我们就完成了第一步了。找出了如何实现旋转。
然后此时,算法就呼吁而出了,完全可以开辟一个n*n的的空间,将当前位置放到对应位置上,此时的时间复杂度为O(n),空间复杂度为O(n)。注:此时的n为总数据量,并非单行的长度

4.算法的逻辑优化

虽然此时找出了单个元素的旋转实现策略,但是整体实现依旧有点复杂,比如00和03交换位置,此时00位置正确,但是03位置错误。此时很多人就觉得这个方法应该走不通,想换条路了。我之前也是这样的,但是在算法上我们应该相信自己的第一思路,既然错那就让它错的更彻底吧。00《-》03,此时03不该在00位置上,但是为了让它错的有价值,让它和本该在00位置上的30交换位置,然后此时00 30 均在正确位置上,03不该在30位置,此时我们发现在让它和本该在3 0位置上的33交换位置之后这四个的位置就均正确了,刚好一个循环。并且此时每确定4个点的位置只用了3个交换。因此时间复杂度降低为3/4n,相比于n是有了较大的提升,并且此时不需要额外的空间存储,空间复杂度仅为O(1)。

总结

1.切入点:算法逻辑通过举例+抽象实现 2.算法优化:空间复杂度、时间复杂度的优化(这个就需要读者自己来实现了,但是大多都是空间换时间、时间换空间的思想)。

猜你喜欢

转载自blog.csdn.net/JasonLee97/article/details/109288366