矩阵“层”旋转

时间:2019-07-20 06:51:11

标签: java matrix rotation

考虑阶数为m * n的矩阵。

它有l层。

我需要沿逆时针方向旋转每一层。


Like this


这是我想出的代码。

        int a1=0; // a1,a2,a3,a4 are counters which start at beginning and the end of each row and column and are then moved to the next layers
        int a2=m-1;
        int a3=n-1;
        int a4=0;
        for(int j=0;j<l;j++) // l is the layers of the matrix
        {
            c=rotate(a,a1,a2,a3,a4);
            a1++;
            a2--;
            a3--;
            a4++; 
        }

这是Rotate方法,它将传递的数组a旋转1个单位

public static int[][] rotate(int a[][],int a1,int a2,int a3,int a4){
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(j==a1 && i<a2)   
                c[i+1][j]=a[i][j]; 
            if(i==a2&& j<a3) 
                c[i][j+1]=a[i][j];
            if(j==a3 && i>a4)   
                c[i-1][j]=a[i][j];
            if(i==a4 && j>a1)     
                c[i][j-1]=a[i][j];}}
    return c;}

请注意,c是全局变量,它是要打印的2D数组。

这可以正常旋转一遍。

但是我需要旋转矩阵“ r”次。

为此,我尝试了这个

for(int i=0;i<r;i++)
    {
        int a1=0;
        int a2=m-1;
        int a3=n-1;
        int a4=0;
        for(int j=0;j<l;j++)
        {
            c=rotate(c,a1,a2,a3,a4); // c was initialized to a 
            a1++;
            a2--;
            a3--;
            a4++; 
        }  
    }

但是这给出了一个非常奇怪的输出,其中大多数空格都用整数2填充。

有没有更简单的方法?我正在考虑用rotate()中的c [i + r] [j]替换c [i + 1] [j],即用rotate()中的r替换1,但是即使这样,在某些地方它也会输出零

public static int[][] rotate(int a[][],int a1,int a2,int a3,int a4){
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(j==a1 && i+r<a2)   //a1,a2
                c[i+r][j]=a[i][j]; 
            if(i==a2 && j+r<a3) //a2,a3
                c[i][j+r]=a[i][j];
            if(j==a3 && i-r>a4)   //a3,a4
                c[i-r][j]=a[i][j];
            if(i==a4 && j-r>a1)     //a4,a1
                c[i][j-r]=a[i][j];}}
    return c;}

我应该如何解决?

2 个答案:

答案 0 :(得分:0)

TLDR;

[SPOILER:下面的完整代码]

几个月前,我在Hackerrank上遇到了这个问题,这是我的代码:

public class Sample {

    int rotation;

    public static void main(String[] args) {
        Sample mr = new Sample();
        String[][] matrix = mr.readMatrix();
        matrix = mr.rotateMatrix(matrix);
        mr.printMatrix(matrix);
    }

    public String[][] rotateMatrix(String[][] matrix) {

        int rows = matrix.length;
        int cols = matrix[0].length;

        String[][] rotatedMatrix = new String[rows][cols];

        // Reading layers
        List<String> layer;
        List<List<String>> layers = new ArrayList<>((Math.max(rows,cols) / 2) + 1);

        int startRow = 0;
        int startCol = 0;

        boolean finished = false;
        while (!finished) {

            int maxRows = rows - startRow;
            int maxCols = cols - startCol;

            layer = new ArrayList<String>(maxRows*2 + maxCols*2);

            // Top layer
            for (int j=startCol; j<maxCols; j++) {
                layer.add(matrix[startRow][j]);
            }

            // Right layer
            for (int i=startRow+1; i<maxRows-1; i++) {
                layer.add(matrix[i][maxCols-1]);
            }

            // Bottom layer
            for (int j=maxCols-1; j>=startCol; j--) {
                layer.add(matrix[maxRows-1][j]);
            }

            // Left layer
            for (int i=maxRows-2; i>=startRow+1; i--) {
                layer.add(matrix[i][startCol]);
            }

            layers.add(layer);

            startRow++;
            startCol++;

            if (startCol > (cols/2) || startRow > (rows/2)) {
                finished = true;
            }
        }

        // Rotating layers
        for (List<String> l : layers) {
            rotateList(l);
        }

        // Filling new matrix
        startRow = 0;
        startCol = 0;
        int layerCount = 0;
        finished = false;
        while (!finished) {

            int maxRows = rows - startRow;
            int maxCols = cols - startCol;

            layer = layers.get(layerCount++);

            // Top layer
            for (int j=startCol; j<maxCols; j++) {
                rotatedMatrix[startRow][j] = layer.remove(0);
            }

            // Right layer
            for (int i=startRow+1; i<maxRows-1; i++) {
                rotatedMatrix[i][maxCols-1] = layer.remove(0);
            }

            // Bottom layer
            for (int j=maxCols-1; j>=startCol; j--) {
                rotatedMatrix[maxRows-1][j] = layer.remove(0);
            }

            // Left layer
            for (int i=maxRows-2; i>=startRow+1; i--) {
                rotatedMatrix[i][startCol] = layer.remove(0);
            }

            layers.add(layer);

            startRow++;
            startCol++;

            if (startCol > (cols/2) || startRow > (rows/2)) {
                finished = true;
            }

        }

        return rotatedMatrix;
    }

    private void rotateList(List<String> list) {

        if (list.size() == 0) {
            return;
        }

        int length = list.size();
        int rotate = this.rotation;

        // Calculating minimum number of rotations
        if (rotate > length) {
            rotate = rotate - (rotate / length) * length ;
        }

        for (int i=0; i<rotate; i++) {
            String v = list.remove(0);
            list.add(v);
        }
    }

    public String[][] readMatrix() {

        Scanner scanner = new Scanner(System.in);

        int rows = scanner.nextInt();
        int cols = scanner.nextInt();

        this.rotation = scanner.nextInt();

        String[][] matrix = new String[rows][cols];

        for (int i=0; i<rows; i++) {
            for (int j=0; j<cols; j++) {
                matrix[i][j] = scanner.next();
            }
        }

        return matrix;
    }

    public void printMatrix(String[][] matrix) {

        for (int i=0; i<matrix.length; i++) {
            for (int j=0; j<matrix[0].length; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.print("\n");
        }
    }
}

希望这会有所帮助。祝你好运。

答案 1 :(得分:0)

这是我如何解决此问题的高级概述。也许不是最有效的解决方案,所以让我知道您是否可以改进。

  1. 我们应该使用模来“旋转”矩阵,因此首先形成一个环阵列,从最外层的环开始,到最内层的环结束。

    在这里,我在环上定义了几个关键点:top_rightbottom_rightbottom_left,其中每个点都对应于环上的索引。使用这些点来确定将点映射到矩阵上的位置。

  2. 现在,像使用常规数组旋转一样,使用rotations % ring_length作为指针,从环形数组中重建矩阵。