方阵旋转异常:第二次旋转后结果与目标矩阵不匹配
我太懂这种感受了——明明理论上旋转180度(也就是两次90度旋转)后的矩阵应该和目标tar严丝合缝,但实际跑起来就是对不上,这种细节上的逻辑bug真的挺磨人的。咱先一步步拆解问题,找找哪里出了问题。
首先先明确预期:你的输入矩阵mat是
int[][] mat = {{0, 0, 0}, {0, 1, 0}, {1, 1, 1}};
180度旋转后的正确目标矩阵(也就是你没写完的tar)应该是:
int[][] tar = {{1, 1, 1}, {0, 1, 0}, {0, 0, 0}};
每个元素的位置对应关系是原位置(i,j)转到(n-1-i, n-1-j)(n是矩阵边长,这里是3),这个是理论上的正确结果。
接下来,大概率是你的旋转逻辑出了下面几种问题之一:
坑1:旋转时直接修改原数组,且in-place旋转的逻辑有错误
很多人写顺时针90度旋转时,会用“转置+左右翻转”的思路,但如果步骤顺序错了(比如先翻转再转置),或者循环边界写不对,结果就会完全跑偏。比如正确的顺时针90度in-place旋转代码应该是这样的:public static void rotateClockwise(int[][] mat) { int n = mat.length; // 第一步:转置矩阵 for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { int temp = mat[i][j]; mat[i][j] = mat[j][i]; mat[j][i] = temp; } } // 第二步:左右翻转每一行 for (int i = 0; i < n; i++) { for (int j = 0; j < n/2; j++) { int temp = mat[i][j]; mat[i][j] = mat[i][n-1-j]; mat[i][n-1-j] = temp; } } }你可以对比下自己的代码,是不是转置和翻转的顺序搞反了,或者循环里的j的范围写错了(比如转置时j从0开始而不是i,这样会把元素交换两次又回到原位)。
坑2:旋转函数返回新数组,但你没更新原引用
如果你的旋转函数是创建一个新矩阵返回(不是in-place修改原矩阵),那两次旋转时必须把每次的返回值重新赋值给mat,比如:// 错误写法:两次都用原mat旋转,结果等于只旋转了一次 rotateClockwise(mat); rotateClockwise(mat); // 正确写法:用每次旋转后的新数组作为下一次的输入 mat = rotateClockwise(mat); mat = rotateClockwise(mat);这种坑我之前也踩过,当时以为函数会自动修改原数组,结果发现每次都是基于初始矩阵旋转,自然和预期对不上。
坑3:旋转方向搞混了
比如第一次用了顺时针90度,第二次不小心用了逆时针90度,那两次旋转等于抵消了,结果还是原矩阵,当然和目标tar不匹配。你得确保两次旋转的方向完全一致。
最后给你个快速排查的小技巧:先单独跑第一次旋转,看看结果是不是
1 0 0 1 1 0 1 0 0
如果第一次的结果就不对,那问题肯定出在第一次旋转的逻辑里,先把第一次的bug修好,第二次旋转自然就会得到正确的180度结果啦。
内容来源于stack exchange




