【问题标题】:Rotating a NxN matrix in Java在 Java 中旋转 NxN 矩阵
【发布时间】:2014-11-11 00:17:36
【问题描述】:

这是来自 Cracking the Coding Interview 的一个问题。解决方案说程序先旋转外边缘,然后再旋转内边缘。但是,我在遵循两个 for 循环的逻辑时遇到了麻烦。

有人能解释一下代码的逻辑吗(例如他们为什么要做“layer top”和“bottom -> left”的四个步骤等)?顺便说一句,在编码面试中提出这个问题时,一个人的思维过程是怎样的?

给定一个由 NxN 矩阵表示的图像,其中每个像素 image 是 4 个字节,写一个方法将图像旋转 90 度。 你能做到这一点吗?

public static void rotate(int[][] matrix, int n) {
    for (int layer = 0; layer < n / 2; ++layer) {
        int first = layer;
        int last = n - 1 - layer;
        for(int i = first; i < last; ++i) {
            int offset = i - first;
            int top = matrix[first][i]; // save top

            // left -> top
            matrix[first][i] = matrix[last-offset][first];          

            // bottom -> left
            matrix[last-offset][first] = matrix[last][last - offset]; 

            // right -> bottom
            matrix[last][last - offset] = matrix[i][last]; 

            // top -> right
            matrix[i][last] = top; // right <- saved top
        }
    }
}

【问题讨论】:

    标签: java matrix rotational-matrices


    【解决方案1】:

    这是我对这个问题的 100% 结果提交

    首先,我将二维数组列表逐层分解为一维数组列表, 然后旋转一维矩阵 然后再次放入矩阵形式 在将二维数组列表分解为一维数组列表时,我保存了数组中元素的位置 这样我们就可以将旋转的矩阵放在那个位置

    import java.io.*;
    import java.math.*;
    import java.security.*;
    import java.text.*;
    import java.util.*;
    import java.util.concurrent.*;
    import java.util.function.*;
    import java.util.regex.*;
    import java.util.stream.*;
    import static java.util.stream.Collectors.joining;
    import static java.util.stream.Collectors.toList;
    
    public class Solution {
        static List<Integer[]> storePosition = new ArrayList<>();
    
        public static ArrayList<Integer> rotateOneDArray(List<Integer> arr, int K) {
            int[] A = arr.stream().mapToInt(i -> i).toArray();
            // write your code in Java SE 8
    
            int r = K % (A.length);
            int[] ans = new int[A.length];
            int y;
            for (int i = 0; i < A.length; i++) {
                y = i - r;
                if (y < 0) {
                    y += A.length;
                }
                ans[y] = A[i];
            }
            return (ArrayList<Integer>) Arrays.stream(ans).boxed().collect(Collectors.toList());
        }
    
        static ArrayList<ArrayList<Integer>> getLinearMatrix(List<List<Integer>> matrix) {
            ArrayList<ArrayList<Integer>> linear = new ArrayList<ArrayList<Integer>>();
            int M = matrix.get(0).size();
            int N = matrix.size();
            int m = M, n = N, i, j, counter = 0;
            Integer[] pos = new Integer[2];
            while (m >= 2 && n >= 2) {
                i = counter;
                j = counter;
    
                ArrayList<Integer> list = new ArrayList<>((m + n - 2) * 2);
    
                while (j < M - counter) {
                    list.add(matrix.get(i).get(j));
                    pos = new Integer[2];
                    pos[0] = i;
                    pos[1] = j;
                    storePosition.add(pos);
                    ++j;
                }
                --j;
                ++i;
                while (i < N - counter) {
                    list.add(matrix.get(i).get(j));
                    pos = new Integer[2];
                    pos[0] = i;
                    pos[1] = j;
                    storePosition.add(pos);
                    ++i;
                }
                --i;
                --j;
                while (j >= counter) {
                    list.add(matrix.get(i).get(j));
                    pos = new Integer[2];
                    pos[0] = i;
                    pos[1] = j;
                    storePosition.add(pos);
                    --j;
                }
                ++j;
                --i;
                while (i > counter) {
                    list.add(matrix.get(i).get(j));
                    pos = new Integer[2];
                    pos[0] = i;
                    pos[1] = j;
                    storePosition.add(pos);
                    --i;
                }
                linear.add(list);
                ++counter;
                m -= 2;
                n -= 2;
            }
            return linear;
        }
    
        // Complete the matrixRotation function below.
        static void matrixRotation(List<List<Integer>> matrix, int r) {
            int m = matrix.get(0).size();
            int n = matrix.size();
    
            ArrayList<ArrayList<Integer>> linearMat = getLinearMatrix(matrix);
            ArrayList<ArrayList<Integer>> rotatedLinearMat = new ArrayList<ArrayList<Integer>>();
    
            for (int f = 0; f < linearMat.size(); f++) {
    
                rotatedLinearMat.add(f, rotateOneDArray(linearMat.get(f), r));
            }
    
            int p = 0;
    
            Integer[][] result = new Integer[n][m];
            for (int i = 0; i < rotatedLinearMat.size(); ++i) {
                for (int j = 0; j < rotatedLinearMat.get(i).size(); ++j) {
                    result[storePosition.get(p)[0]][storePosition.get(p)[1]] = rotatedLinearMat.get(i).get(j);
                    ++p;
                }
            }
    
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    System.out.print(result[i][j] + " ");
                }
                System.out.println();
            }
        }
    
        public static void main(String[] args) throws IOException {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
    
            String[] mnr = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
    
            int m = Integer.parseInt(mnr[0]);
            int n = Integer.parseInt(mnr[1]);
            int r = Integer.parseInt(mnr[2]);
    
            List<List<Integer>> matrix = new ArrayList<>();
    
            IntStream.range(0, m).forEach(i -> {
                try {
                    matrix.add(
                            Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
                                    .map(Integer::parseInt)
                                    .collect(toList())
                    );
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            });
    
            matrixRotation(matrix, r);
    
            bufferedReader.close();
        }
    }
    

    【讨论】:

      【解决方案2】:

      刚刚看到有一种更简单的方法可以通过重构“last-offset”来编写代码:

      public static void rotateInPlace90DegreesClockwise(int[][] matrix) {
          int n = matrix.length;
          int half = n / 2;
      
          for (int layer = 0; layer < half; layer++) {
              int first = layer;
              int last = n - 1 - layer;
      
              for (int i = first; i < last; i++) {
                  int offset = i - first;
                  int j = last - offset;
                  int top = matrix[first][i]; // save top
      
                  // left -> top
                  matrix[first][i] = matrix[j][first];
      
                  // bottom -> left
                  matrix[j][first] = matrix[last][j];
      
                  // right -> bottom
                  matrix[last][j] = matrix[i][last];
      
                  // top -> right
                  matrix[i][last] = top; // right <- saved top
              }
          }
      }
      

      【讨论】:

      • 你能解释一下吗?这是什么逻辑?
      【解决方案3】:

      这是 C# 中的解决方案。每个N x N 矩阵都有底(N/2) 平方循环。

      例如- 4×45×5 都将有 2 个可旋转层。

      以下角组合识别位置:

      (top,left) points to (first,first) --> 0,0
      (top,right) points to (first,last) --> 0,n
      (bottom,left) points to (last,first) --> n,0
      (bottom,right) points to (last,last) --> n,n
      

      这是将矩阵旋转 90 度的代码:

      public static void RotateMatrixBy90Degress(int[][] matrix) {
          int matrixLen = matrix.Length;
          for (int layer = 0; layer < matrixLen / 2; layer++) {
              int first = layer;
              int last = matrixLen - first - 1;
      
              for (int i = first; i < last; i++) {
                  int offset = i - first;
                  int lastMinusOffset = last - offset;
                  // store variable in a temporary variable
                  int top = matrix[first][i];
      
                  // move values from left --> top
                  matrix[first][i] = matrix[lastMinusOffset][first];
      
                  // move values from bottom --> left
                  matrix[lastMinusOffset][first] = matrix[last][lastMinusOffset];
      
                  // move values from right --> bottom
                  matrix[last][lastMinusOffset] = matrix[i][last];
      
                  // move values from top  --> right
                  matrix[i][last] = top;
              }
          }
      }
      

      这是在矩阵中生成随机数的代码。

      public static void RotateMatrixImplementation(int len) {
          int[][] matrix = new int[len][];
          var random = new Random();
          for (int i = 0; i < matrix.Length; i++) {
              matrix[i] = new int[len]; // Create inner array
              for (int j = 0; j < matrix[i].Length; j++) {
                  //generate random numbers
                  matrix[i][j] = random.Next(1, Convert.ToInt32(Math.Pow(len, 3)));
              }
          }
          RotateMatrixBy90Degress(matrix);
      }
      

      【讨论】:

        【解决方案4】:

        在此代码中,您将能够转动 NxN 矩阵一次,您也可以选择方向 1 表示顺时针,-1 表示相反。 在 rotateMatrix 方法中,每个角都需要 for-for 循环。

        公共类 JavaApplication144 {

        public static void main(String[] args) {
            Scanner s = new Scanner(System.in);
            int matrix[][] = {{56, 12, 8, 90, 40}, {87, 76, 99, 1, 32}, {34, 43, 25, 78, 6}, {39, 555, 65, 88, 3}, {44, 75, 77, 14, 10}};
            print();
        }
        

        方法如下:

        static int[][] shiftingmatris(int[][] p_matris, int dırectıon) {
            int[][] tempmatris = new int[p_matris.length][p_matris[0].length];
        
            if (dırectıon == -1) {
                for (int i = 0; i < p_matris.length; i++) {
                    for (int j = 0; j < p_matris[0].length; j++) {
                        if (i == 0 && j != p_matris[0].length - 1) {
                            tempmatris[i][j + 1] = p_matris[i][j];
                        } else if (i == p_matris.length - 1 && j != 0) {
                            tempmatris[i][j - 1] = p_matris[i][j];
                        }
                    }
                }
                for (int i = 0; i < p_matris.length; i++) {
                    for (int j = 0; j < p_matris[0].length; j++) {
                        if (j == 0 && i != 0) {
                            tempmatris[i - 1][j] = p_matris[i][j];
                        } else if (j == p_matris[1].length - 1 && i != p_matris.length - 1) {
                            tempmatris[i + 1][j] = p_matris[i][j];
        
                        }
                    }
                }
        
            } else if (dırectıon == 1) {
                for (int i = 0; i < p_matris.length; i++) {
                    for (int j = 0; j < p_matris[1].length; j++) {
                        if (i == 0 && j != 0) {
                            tempmatris[i][j - 1] = p_matris[i][j];
        
                        } else if (i == p_matris.length - 1 && j != p_matris[0].length - 1) {
                            tempmatris[i][j + 1] = p_matris[i][j];
                        }
                    }
                }
                for (int i = 0; i < p_matris.length; i++) {
                    for (int j = 0; j < p_matris[0].length; j++) {
                        if (j == 0 && i != p_matris.length - 1) {
                            tempmatris[i + 1][j] = p_matris[i][j];
                        } else if (j == p_matris[0].length - 1 && i != 0) {
                            tempmatris[i - 1][j] = p_matris[i][j];
        
                        }
                    }
                }
        
            }
        
            for (int i = 1; i < p_matris.length - 1; i++) {
                for (int j = 1; j < p_matris[1].length - 1; j++) {
                    tempmatris[i][j] = p_matris[i][j];
                }
            }
            return tempmatris;
        }
        

        }

        您还需要打印矩阵。用那个方法是可以的:

        public static void print(){
         Scanner s = new Scanner(System.in);
            System.out.println("times of rotate: ");
            int dondurme = s.nextInt();
            System.out.println("direction?");
            int dırectıon = s.nextInt();
            int matrix[][] = {{56, 12, 8, 90, 40}, {87, 76, 99, 1, 32}, {34, 43, 25, 78, 6}, {39, 555, 65, 88, 3}, {44, 75, 77, 14, 10}};
            System.out.println(" ");
            for (int i = 0; i < matrix.length; i++) {
                System.out.println(" ");
                for (int j = 0; j < matrix.length; j++) {
                    System.out.print(" ");
                    System.out.print(matrix[i][j] + " ");
                }
            }
        
            for (int i = 0; i < dondurme; i++) {
                matrix = shiftingmatris(matrix, dırectıon);
            }
            System.out.println(" ");
            for (int i = 0; i < matrix.length; i++) {
                System.out.println(" ");
                for (int j = 0; j < matrix.length; j++) {
                    System.out.print(" ");
                    System.out.print(matrix[i][j] + " ");
                }
            }
        }
        

        【讨论】:

          【解决方案5】:

          是的,该代码非常丑陋且难以阅读 - 主要是因为作者没有使用描述性很强的变量名称。我使用相同的原理解决了同样的问题(将方阵视为一组同心正方形,然后一次旋转一个从外部正方形到内部正方形)。这是我的解决方案和我的思考过程的解释。

          代码

          我使用了 C#,但语法几乎与 Java 相同。复制/粘贴后,只需将a.Length 更改为a.length,它应该是语法正确的Java。

          void swap(int[][] a, int g, int h, int i, int j) {
              int temp = a[g][h];
              a[g][h] = a[i][j];
              a[i][j] = temp;
          }
          
          int[][] rotateImage(int[][] a) {
              if (a.Length > 1) {
                  int topRow = 0, bottomRow = a.Length - 1, leftCol = topRow, rightCol = bottomRow;
          
                  while (topRow < bottomRow && leftCol < rightCol) {
                      swap(a, topRow, leftCol, topRow, rightCol);
                      swap(a, topRow, leftCol, bottomRow, leftCol);
                      swap(a, bottomRow, leftCol, bottomRow, rightCol);
          
                      for (int i = topRow + 1, j = bottomRow - 1; i < bottomRow && j > topRow; i++, j--) {
                          swap(a, topRow, i, i, rightCol);
                          swap(a, topRow, i, bottomRow, j);
                          swap(a, topRow, i, j, leftCol);
                      }
          
                      topRow++; leftCol++;
                      bottomRow--; rightCol--;
                  }
              }
          
              return a;
          }
          

          您可能会注意到我可能会删除变量leftColrightCol,因为它们分别保持等于topRowbottomRow。我不这样做的原因是因为我觉得它使代码更容易理解。

          解释

          首先,请注意,如果给定一个1x1 矩阵,我们会返回原始矩阵,因为只有一个像素,这意味着不需要旋转。

          接下来,假设我们得到以下2x2 矩阵:

          1 2
          3 4
          

          你可以在三个交换中旋转这个矩阵。 Top Left -&gt; Top RightTop Left -&gt; Bottom LeftTop Left -&gt; Bottom Right

          4 1
          2 3
          

          现在假设我们得到了以下3x3 矩阵:

          1 2 3
          4 5 6
          7 8 9
          

          请注意,内部正方形是我们的老朋友1x1 矩阵。重要的是要意识到n &gt; 1 &amp;&amp; n % 2 != 0 的所有方阵最终都会减少到中心的1x1。同样,n &gt; 1 &amp;&amp; n % 2 == 0 的位置将减少到中心的2x2。我们可以用同样的方式处理这两种情况。

          同样,我们将从外部正方形的角开始。我们使用我们熟悉的前三个交换:Top Left -&gt; Top RightTop Left -&gt; Bottom LeftTop Left -&gt; Bottom Right

          7 2 1
          4 5 6
          9 8 3
          

          注意矩阵几乎是旋转的;只是外侧中心的那四个讨厌的值。但是,还要注意,这些值中的每一个都距离我们旋转的角只有一个位置。如果我们继续我们使用固定起始点进行交换的模式,就像我们对角点一样,我们可以像这样旋转最后四个值:Top Middle -&gt; Right MiddleTop Middle -&gt; Bottom MiddleTop Middle -&gt; Left Middle。就指数而言,“中上”只是“左上”加一。同样,“右中”只是“右上”加一。对于某些指数,从超大指数 (n - 1) 开始并递减是有意义的。我将较小的中间索引称为i,将较大的中间索引称为j

          7 4 1
          8 5 2
          9 6 3
          

          旋转 2x2 矩阵需要 3 次交换,旋转 3x3 矩阵需要 6 次交换,一般来说,旋转 nxn 矩阵需要 n! 交换。我的while 循环旋转矩阵中每个同心正方形的角(并且每个正方形都小于前一个正方形),然后我的for 循环处理沿边缘的角之间的值。一直这样下去,直到没有更多的内部正方形可以旋转,或者剩下的唯一内部正方形是一个1x1 矩阵。

          【讨论】:

            【解决方案6】:

            我正在写这个答案,因为即使在阅读了上面 Jason 发布的答案之后(这很好并且确实解决了我的几个问题),我仍然不清楚变量“偏移”在其中扮演什么角色逻辑,所以花了几个小时来理解这一点,我想与大家分享。

            这里使用了很多变量,理解每个变量的重要性很重要。

            如果你看变量'first',它没有用,它本质上是'layer'本身,'first'在整个逻辑中根本没有被修改。所以我删除了“第一个”变量(它有效,请提前阅读)。

            为了了解这些值在内部 for 循环的每次迭代中如何变化,我打印了这些变量的值。查看输出并了解当我们在内部 for 循环中从一个角移动到另一个角时哪些值会发生变化,哪些值在遍历单个层时保持不变,哪些值仅在我们更改层时才会发生变化。

            内循环的一次迭代移动一个块。 随着我们向内移动,移动单个层所需的迭代次数会发生变化。变量“last”为我们完成了这项工作,它限制了内循环(限制内层并阻止我们超越外壳,建立在 Jason 使用的命名法的基础上)

            是时候研究输出了

            我使用的是 6x6 矩阵。

            Input: 
            
             315 301 755 542 955 33
             943 613 233 880 945 280
             908 609 504 61 849 551
             933 251 706 707 913 917
             479 785 634 97 851 745
             472 348 104 645 17 273
            
            --------------Starting an iteration of OUTER FOR LOOP------------------
            
            --------------Starting an iteration of inner for loop------------------
            layer =0
            last =5
            i =0
            buffer = 315
            offset = i-layer = 0
            Current Status: 
            
             472 301 755 542 955 315
             943 613 233 880 945 280
             908 609 504 61 849 551
             933 251 706 707 913 917
             479 785 634 97 851 745
             273 348 104 645 17 33
            --------------Finished an iteration of inner for loop------------------
            
            --------------Starting an iteration of inner for loop------------------
            layer =0
            last =5
            i =1
            buffer = 301
            offset = i-layer = 1
            Current Status: 
            
             472 479 755 542 955 315
             943 613 233 880 945 301
             908 609 504 61 849 551
             933 251 706 707 913 917
             17 785 634 97 851 745
             273 348 104 645 280 33
            --------------Finished an iteration of inner for loop------------------
            
            --------------Starting an iteration of inner for loop------------------
            layer =0
            last =5
            i =2
            buffer = 755
            offset = i-layer = 2
            Current Status: 
            
             472 479 933 542 955 315
             943 613 233 880 945 301
             908 609 504 61 849 755
             645 251 706 707 913 917
             17 785 634 97 851 745
             273 348 104 551 280 33
            --------------Finished an iteration of inner for loop------------------
            
            --------------Starting an iteration of inner for loop------------------
            layer =0
            last =5
            i =3
            buffer = 542
            offset = i-layer = 3
            Current Status: 
            
             472 479 933 908 955 315
             943 613 233 880 945 301
             104 609 504 61 849 755
             645 251 706 707 913 542
             17 785 634 97 851 745
             273 348 917 551 280 33
            --------------Finished an iteration of inner for loop------------------
            
            --------------Starting an iteration of inner for loop------------------
            layer =0
            last =5
            i =4
            buffer = 955
            offset = i-layer = 4
            Current Status: 
            
             472 479 933 908 943 315
             348 613 233 880 945 301
             104 609 504 61 849 755
             645 251 706 707 913 542
             17 785 634 97 851 955
             273 745 917 551 280 33
            --------------Finished an iteration of inner for loop------------------
            --------------Finished an iteration of OUTER FOR LOOP------------------
            
            --------------Starting an iteration of OUTER FOR LOOP------------------
            
            --------------Starting an iteration of inner for loop------------------
            layer =1
            last =4
            i =1
            buffer = 613
            offset = i-layer = 0
            Current Status: 
            
             472 479 933 908 943 315
             348 785 233 880 613 301
             104 609 504 61 849 755
             645 251 706 707 913 542
             17 851 634 97 945 955
             273 745 917 551 280 33
            --------------Finished an iteration of inner for loop------------------
            
            --------------Starting an iteration of inner for loop------------------
            layer =1
            last =4
            i =2
            buffer = 233
            offset = i-layer = 1
            Current Status: 
            
             472 479 933 908 943 315
             348 785 251 880 613 301
             104 609 504 61 233 755
             645 97 706 707 913 542
             17 851 634 849 945 955
             273 745 917 551 280 33
            --------------Finished an iteration of inner for loop------------------
            
            --------------Starting an iteration of inner for loop------------------
            layer =1
            last =4
            i =3
            buffer = 880
            offset = i-layer = 2
            Current Status: 
            
             472 479 933 908 943 315
             348 785 251 609 613 301
             104 634 504 61 233 755
             645 97 706 707 880 542
             17 851 913 849 945 955
             273 745 917 551 280 33
            --------------Finished an iteration of inner for loop------------------
            --------------Finished an iteration of OUTER FOR LOOP------------------
            
            --------------Starting an iteration of OUTER FOR LOOP------------------
            
            --------------Starting an iteration of inner for loop------------------
            layer =2
            last =3
            i =2
            buffer = 504
            offset = i-layer = 0
            Current Status: 
            
             472 479 933 908 943 315
             348 785 251 609 613 301
             104 634 706 504 233 755
             645 97 707 61 880 542
             17 851 913 849 945 955
             273 745 917 551 280 33
            --------------Finished an iteration of inner for loop------------------
            --------------Finished an iteration of OUTER FOR LOOP------------------
            
             472 479 933 908 943 315
             348 785 251 609 613 301
             104 634 706 504 233 755
             645 97 707 61 880 542
             17 851 913 849 945 955
             273 745 917 551 280 33
            

            抱歉,除了思考 layer、i 和 offset 的值如何变化之外,别无他法,以了解这里到底发生了什么。

            终于有代码了

            这是我首先删除不必要的代码并添加所有打印语句的代码,以防万一有人想玩更多。此代码还具有随机矩阵初始化和打印:

            package com.crackingthecodinginterview.assignments.chap1;
            
            public class Problem6RotateMatrix90 {
            
                public static void main(String args[]){
                    int[][] matrix = new int[6][6];
                    initializeMatrix(matrix,6);
                    System.out.println("Input: ");
                    printMatrix(matrix,6);
                    rotate(matrix,6);
                    printMatrix(matrix,6);
                }
            
                public static void rotate(int[][] matrix, int n) {
                    for (int layer = 0; layer < n / 2; ++layer) {
                        System.out.println("\n--------------Starting an iteration of OUTER FOR LOOP------------------");
            
                        int last = n - 1 - layer;
                        for(int i = layer; i < last; ++i) {
                            int offset = i - layer;
                            int buffer = matrix[layer][i]; // save top
                            System.out.println("\n--------------Starting an iteration of inner for loop------------------");
                            System.out.println("layer ="+layer);
            
                            System.out.println("last ="+last);
                            System.out.println("i ="+i);
            
                            System.out.println("buffer = "+buffer);
                            System.out.println("offset = i-layer = "+ offset);
            
                            // left -> top
                            matrix[layer][i] = matrix[last-offset][layer];          
            
                            // bottom -> left
                            matrix[last-offset][layer] = matrix[last][last - offset]; 
            
                            // right -> bottom
                            matrix[last][last - offset] = matrix[i][last]; 
            
                            // top -> right
                            matrix[i][last] = buffer; // right <- saved top
            
                            //print
                            System.out.println("Current Status: ");
                            printMatrix(matrix,6);
                            System.out.println("--------------Finished an iteration of inner for loop------------------");
                        }
                        System.out.println("--------------Finished an iteration of OUTER FOR LOOP------------------");
            
                    }
                }
            
                public static void printMatrix(int[][] matrix,int n){
                    System.out.print("\n");
                    for(int i=0;i<n;i++){
                        for(int j=0;j<n;j++){
                            System.out.print(" "+matrix[i][j]);
                        }
                        System.out.print("\n");
                    }
                }
            
                public static void initializeMatrix(int[][] matrix,int n){
                    for(int i=0;i<n;i++){
                        for(int j=0;j<n;j++){
                            matrix[i][j]=(int) (Math.random() * 1000);
                        }
                    }
                }
            
            }
            

            【讨论】:

              【解决方案7】:

              这是一个非常适合我的简单解决方案。

               private int[][] rotateMatrix(int[][] matrix)
                  {
                      for(int i=0;i<matrix.length-1;i++)
                      {
                          for(int j =i;j<matrix[0].length;j++)
                          {
                              if(i!=j) {
                                  int temp = matrix[i][j];
                                  matrix[i][j] = matrix[j][i];
                                  matrix[j][i] = temp;
                              }
                          }
                      }
                      return matrix;
                  }
              

              【讨论】:

              • 这会转置矩阵;它不旋转它。给定转置矩阵,您必须反转每一行以获得正确的旋转矩阵。
              【解决方案8】:

              这是我在 JavaScript 中的解决方案,它在行和列之间交换值,从右上角开始,向内直到最左下角的对被交换。

              function rotateMatrix(arr) {
                  var n = arr.length - 1;
              
                  for (var i = 0; i < n; i++) {
                      for (var j = 0; j < n - i; j++) {
                          var temp = arr[i][j];
              
                          arr[i][j] = arr[n - j][n - i]; // top row
                          arr[n - j][n - i] = temp; // right column
                      }
                  }
              
                  return arr;
              }
              

              【讨论】:

                【解决方案9】:

                检查此解决方案以执行此操作。

                public void rotateMatrix(Pixel[][] matrix) {
                
                    for (int i = 0; i < matrix.length / 2; i++) {
                
                        for (int j = 0; j < matrix.length - 1 - 2 * i; j++) {
                            Pixel tmp = matrix[j + i][matrix.length - 1 - i];
                            matrix[j + i][matrix.length - 1 - i] = matrix[i][j + i];
                            matrix[i][j + i] = matrix[matrix.length - 1 - j - i][i];
                            matrix[matrix.length - 1 - j - i][i] = matrix[matrix.length - 1 - i][matrix.length - 1 - j - i];
                            matrix[matrix.length - 1 - i][matrix.length - 1 - j - i] = tmp;
                        }
                    }
                }
                

                【讨论】:

                  【解决方案10】:

                  简单的解决方案是:

                  int[][] a = { {00,01,02  }, { 10,11,12} ,{20,21,22}};
                  System.out.println(" lenght " + a.length);
                  
                  int l = a.length;
                  
                  for (int i = 0; i <l; i++) {
                  
                      for (int j = l - 1; j >= 0; j--) {
                          System.out.println(a[j][i]);
                      }
                  }
                  

                  【讨论】:

                  • 这不会旋转矩阵。它只是打印矩阵的旋转形式。
                  【解决方案11】:

                  概述

                  假设一个样本矩阵可能如下所示:

                  ABCD
                  EFGH
                  IJKL
                  MNOP
                  

                  为了我的解释,ABCD 被认为是第 0 行,EFGH 是第 1 行,依此类推。第 0 行的第一个像素是 A。

                  另外,当我谈到外壳时,我指的是:

                  ABCD
                  E  H
                  I  L
                  MNOP
                  

                  首先让我们看看移动值的代码。

                      int top = matrix[first][i]; // save top
                  

                  第一行缓存顶部位置的值。这指的是由 [first][i] 标识的矩阵顶行的位置。例如:保存A

                      // left -> top
                      matrix[first][i] = matrix[last-offset][first];          
                  

                  下一部分将值从左侧位置移动到顶部位置。例如:将M 放在A 所在的位置。

                      // bottom -> left
                      matrix[last-offset][first] = matrix[last][last - offset]; 
                  

                  下一部分将值从底部位置移动到左侧位置。例如:将P 放在M 所在的位置。

                      // right -> bottom
                      matrix[last][last - offset] = matrix[i][last]; 
                  

                  下一部分将值从右侧位置移动到底部位置。例如:将D 放在P 所在的位置。

                      // top -> right
                      matrix[i][last] = top; // right <- saved top
                  

                  最后一部分将缓存中的值(顶部位置)移动到正确的位置。例如:将A 从第一步放在D 所在的位置。

                  接下来是循环。

                  外部循环从第 0 行运行到总行数的一半。这是因为当你旋转第 0 行时,它也会旋转最后一行,而当你旋转第 1 行时,它也会旋转倒数第二行,以此类推。

                  内部循环从行中的第一个像素位置(或列)运行到最后一个像素位置。请记住,对于第 0 行,这是从像素 0 到最后一个像素,但对于第 1 行,这是从像素 1 到倒数第二个像素,因为第一个和最后一个像素作为第 0 行的一部分旋转.

                  所以外循环的第一次迭代使外壳旋转。换句话说:

                  ABCD
                  EFGH
                  IJKL
                  MNOP
                  

                  变成:

                  MIEA
                  NFGB
                  OJKC
                  PLHD
                  

                  看看外壳如何顺时针旋转,但内核没有移动。

                  然后外循环的第二次迭代导致第二行旋转(不包括第一个和最后一个像素),我们最终得到:

                  MIEA
                  NJFB
                  OKGC
                  PLHD
                  

                  【讨论】:

                  • 感谢您的快速回复,非常感谢您的解释。如果这个问题过于简单,我深表歉意,但我无法在更大范围内理解“左”、“右”、“顶”和“底”是什么以及“层”由什么组成。左边,右边,顶部,底部只是角落吗?每一层都只是向内的正方形的边界吗?
                  • @Jason 感谢您的解释。我似乎无法理解“int offset = i - first;”背后的逻辑在内部循环中。
                  • 书上的解释太没用了,代码不重要,理解逻辑很重要。这个答案在很大程度上起到了很好的作用。真正的挑战是理解所有这些术语代表什么以及它们在内部 for 循环和外部 for 循环中如何变化。尤其是偏移项。
                  • @Jason:完美的解释。喜欢简单。没有假设。
                  • @SaurabhPatil 我在那本书中发现了很多错误。我认为这是一本被高估、过度炒作的书。可能是因为缺乏竞争。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-10-28
                  • 1970-01-01
                  • 2022-12-12
                  • 2022-01-16
                  • 1970-01-01
                  相关资源
                  最近更新 更多