我有一些代码(following this example)从左上角开始遍历矩阵并顺时针旋转。我想基于此创建三种新方法:
为了使这些功能都能正常工作,我需要更改什么?我尝试反转计数器的增量并更改开始/结束行/列,但均未成功。
public static void traverseSpiral(int[][] matrix) {
if(matrix.length == 0|| matrix[0].length == 0) {
return;
}
StringBuffer stringBuffer = new StringBuffer();
int counter = matrix.length * matrix[0].length;
int startRow = 0;
int endRow = matrix.length-1;
int startCol = 0;
int endCol = matrix[0].length-1;
boolean moveCol = true;
boolean leftToRight = true;
boolean upDown = true;
while(counter>0) {
if(moveCol) {
if(leftToRight) {
/* printing entire row left to right */
for(int i = startCol; i <= endCol ; i++){
stringBuffer.append(matrix[startRow][i]);
counter--;
}
leftToRight = false;
moveCol = false;
startRow++;
}
else{
/* printing entire row right to left */
for(int i = endCol ; i >= startCol ; i--){
stringBuffer.append(matrix[endRow][i]);
counter--;
}
leftToRight = true;
moveCol = false;
endRow--;
}
}
else
{
if(upDown){
/* printing column up down */
for(int i = startRow ; i <= endRow ; i++){
stringBuffer.append(matrix[i][endCol]);
counter--;
}
upDown = false;
moveCol = true;
endCol--;
}
else
{
/* printing entire col down up */
for(int i = endRow ; i >= startRow ; i--){
stringBuffer.append(matrix[i][startCol]);
counter--;
}
upDown = true;
moveCol = true;
startCol++;
}
}
}
System.out.println(stringBuffer.toString());
}
最佳答案
代码的问题在于,您将所有代码都转储到一个方法中,这使得代码非常难以阅读,也很难修改(不破坏任何内容)。
由于这是一个面试问题,因此您不仅应该努力找到解决方案,而且还要找到最优雅的解决方案。或最快的解决方案。或最短的。最终,每个程序员在编写代码时都有不同的优先级。但是大多数(如果不是所有程序员)都努力编写好的代码。
好的代码易于阅读,编写和维护。尽管没有什么定义好的代码的确切定义,但克里斯托弗·约翰逊(Kristopher Johnson)发布了this answer,我觉得覆盖基本内容的工作非常好。
考虑将您的代码分解为各个方法,每个方法都有自己的责任。马上,我可以看到四个代码块应该是它们自己的方法(从左到右,从右到左,从上到下和从下到上打印)。这将使您的代码更整洁。
例如,在递归解决此问题的方法中,我将至少有5种方法:
// A method that will handle the traversal of the spiral.
public static String clockwise(int[][] matrix);
// Responsible for printing a column from bottom to top.
public static String up(int[][] matrix, int first, int last);
// Responsible for printing a column from top to bottom.
public static String down(int[][] matrix, int first, int last);
// Responsible for printing a column from right to left.
public static String left(int[][] matrix, int first, int last);
// Responsible for printing a column from left to right.
public static String right(int[][] matrix, int first, int last);
使用这样的方法,实现一种方法以逆时针遍历相同的螺旋将很容易,因为编写另一种方法可以重复使用
up(matrix, first, last)
,down(matrix, first, last)
,left(matrix, first, last)
和right(matrix, first, last)
中的代码,因为:Clockwise = right, down, left, up;
Counter-Clockwise = down, right, up, left;
就个人而言,我更喜欢divide-and-conquer递归方法。由于围绕
3x3
大小的网格螺旋形旋转与绕一圈2x2
的网格螺旋形旋转基本相同,因此您可以使用递归来查找和解决问题的最小版本,并逐步建立解决方案。我强烈建议您独立研究递归和分而治之方法。如果您只是对解决螺旋遍历问题感兴趣,包括顺时针,逆时针,向外顺时针和逆时针向外,请参见GitHub Gist here。
注意:上面的代码按的形式按原样提供,但不保证任何形式的。所以要当心。
关于java - 如何更改此矩阵螺旋遍历的方向和起点?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21108695/