Mirror of Matrix Across Diagonal in Java

2025年5月9日 | 阅读 7 分钟

矩阵对其角线镜像涉及翻转其行和列以对称地反射元素。对于方阵,位置(i, j)处的元素与(j, i)处的元素进行交换。该操作将矩阵转换为其转置,这在各种数学和计算应用中都很有用。

示例

输入

1 2 3

4 5 6

7 8 9

输出

1 4 7

2 5 8

3 6 9

解释

输出是交换对角线上方的每个元素与其下方对应元素的交换结果。该过程有效地将矩阵对其角线进行镜像。它将原始矩阵转换为其转置,其中行变为列,列变为行。

方法 1:使用矩阵转置

算法

步骤 1:理解问题:通过交换位置(i, j)与(j, i)处的元素来镜像矩阵对其角线。它仅适用于行数等于列数的方阵。

步骤 1.1:输入验证:确保输入矩阵是方阵。如果不是,则镜像对其角线是未定义的。

步骤 1.3:处理非方阵:如果输入矩阵不是方阵(即行数不等于列数),则无法执行镜像过程。在这种情况下,有必要拒绝输入或使用适当的错误消息处理该情况,因为镜像对其角线仅对方阵定义。

步骤 2:外循环(行遍历):迭代矩阵的每一行索引 i,从 0 到 n-1,其中 n 是矩阵的行数或列数。

步骤 2.1:外循环(行遍历)

首先迭代矩阵的行。外循环从索引 i=0 开始,一直持续到 i=n-1,其中 n 是矩阵的行数或列数。此循环控制行索引,允许您逐行访问和处理。

步骤 3:内循环(列遍历):对于每一行 i,迭代列 j,从 i+1 开始到 n-1。这确保对角线以上的每个元素都恰好访问一次,避免了重复的交换。

步骤 3.1:内循环(列遍历):对于每一行索引 i,内循环迭代从索引 i+1 到 n-1 的列。这确保只处理对角线以上的元素,因为对角线本身和其下方的每个元素已经在之前的迭代中处理过了。

步骤 4:交换元素:对于每一对 (i,j),交换位置 (i,j) 和 (j,i) 处的元素。使用临时变量来方便交换。

步骤 4.1:循环结束:在所有必要位置的元素交换完成后,循环结束。此时,对角线以上的所有元素都已与其下方的对应元素交换,有效地将矩阵转换为其对其角线的镜像。

步骤 4.3:继续下一对:一旦位置 (i,j) 和 (j,i) 处的元素被交换,过程就会移动到下一对元素。内循环继续,直到当前行 i 的所有相关对都已交换。然后,外循环进入下一行重复此过程。

步骤 5:输出结果:一旦对角线上方的所有元素都与其下方的对应元素交换完毕,矩阵就会被转换。现在行与列已交换,矩阵有效地进行了转置。这会产生一个新矩阵,它对称地反映了其原始结构在其对角线上,完成了镜像过程。

步骤 6:验证结果:输出修改后的矩阵后,重要的是要验证转换是否已正确执行。检查每个元素是否已对其角线进行镜像,并且行是否已正确地与列交换。这确保矩阵准确地表示为其转置,确认镜像操作已成功。

输出

 
1 4 7 
2 5 8 
3 6 9   

复杂度分析

时间复杂度

镜像矩阵对其角线的时空复杂度为 O(n 2),其中 n 是矩阵的大小。这是因为算法在嵌套循环中遍历了矩阵大约一半的元素 n(n-1)/2),这简化为二次复杂度。

空间复杂度

镜像矩阵对其角线的空间复杂度为 O(1),因为转换是就地执行的。该算法在交换过程中仅使用常量额外空间用于临时变量,而与矩阵大小无关,无需额外的数据结构

方法 2:使用递归镜像矩阵

算法

步骤 1:输入验证:确保输入矩阵是方阵,即行数和列数必须相等。如果矩阵不是方阵,则返回错误或适当处理该情况,因为镜像仅对方阵定义。

步骤 2:递归函数设置:创建一个递归函数来执行镜像。该函数将以矩阵和两个索引(行和列)作为参数。它将首先从左上角开始访问矩阵的元素。

步骤 2.1:开始递归:通过使用初始行索引 i=0 和列索引 j=0 调用函数来开始递归。这将开始访问矩阵元素的过程。函数将从左上角开始,并按照递归模式跨对角线交换元素。

步骤 2.2:处理当前元素:在每次递归调用中,检查位置 (i,j) 处的当前元素是否需要交换。如果 j≥i,则在 (i,j) 和 (j,i) 处的元素之间执行交换。然后,函数将通过使用更新后的索引递归调用自身来移动到下一个元素,或者向右移动,或者转到下一行。

步骤 3:基本条件:递归需要一个基本条件来在完成处理整个矩阵时停止。当行索引到达矩阵末尾时,就会发生这种情况。一旦满足此条件,递归就会停止。

步骤 4:交换元素:在每次递归调用中,函数会交换位于位置 (i,j) 和 (j,i) 的元素。这些位置位于矩阵对角线的上方和下方。通过交换这些元素,矩阵会对其角线进行镜像。

步骤 5:移动到下一对:交换 (i,j) 和 (j,i) 处的元素后,函数通过增加列索引 j 递归地移动到下一列。一旦处理完给定行的所有列,行索引 i 就会增加,然后继续。

步骤 5.1:检查行结束:在移动到下一对之前,检查当前列索引 j 是否已到达行的末尾。如果是,则将 j 重置为 i+1,并增加行索引 i 以开始处理下一行。这确保在继续之前处理当前行的所有列。

步骤 6:递归结束:一旦处理完所有行并完成了所有必要的交换,递归就会结束。此时,矩阵已被镜像对其角线,可以返回结果。

步骤 6.1:最终递归调用检查:在最终递归调用中,验证对角线上方的所有元素是否已与其下方的对应元素交换。确保所有行和列都已满足基本条件。此步骤确认递归已完成其任务,并且矩阵已完全镜像对其角线。

步骤 7:输出结果:递归函数完成后,矩阵将被转置,行和列在其对角线上对称交换。矩阵现在已被镜像,可以打印或返回结果。

输出

 
1 2 3 
4 5 6 
7 8 9   

复杂度分析

时间复杂度

此递归方法的时空复杂度为 O(n 2),其中 n 是矩阵的大小。在递归期间,每个元素都会被访问一次,并且对于每个元素,都会执行一次交换操作。由于递归会遍历所有矩阵元素,因此总体复杂度是二次的。

空间复杂度

空间复杂度:此递归方法的空间复杂度为 O(n),这是由于递归堆栈。由于递归逐行遍历并处理每个元素,因此递归堆栈的深度最多可以达到 n,其中 n 是矩阵的行数或列数。


下一个主题Java混淆器