在2D数组中旋转内部正方形

时间:2017-08-26 01:21:41

标签: java algorithm performance matrix multidimensional-array

我想在2D数组中旋转内部正方形,如下面的“Sample”图像:

Sample

给出左上角和右下角位置。

我试图将它拆分为另一个2d阵列然后旋转它。但它需要大O循环运行时和内存。

static int[][] rotateMatrix(int[][] subSquare) {
    int n = subSquare.length;
    int[][] temp = new int [n][n];
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            temp[i][j] = subSquare[n - j - 1][i];
        }
    }
    return temp;
}

static int[][] getInnerSquare(int[][] square, int ai, int bi, int di){
    int g = 0, h = 0;
    int[][] innerSquare = new int[di+1][di+1];
    for(int k = ai - 1; k < ai + di; k++) {
        for(int j = bi - 1; j < bi + di; j++) {
            innerSquare[g][h] = square[k][j];
            h++;
        }
        g++;
        h=0;
    }
    return innerSquare;
}
    static void replaceInnerSquare(int[][] square, int[][] innerSquare, int ai, int bi, int di) {
    int g = 0, h = 0;
    for(int i = ai - 1; i < ai + di; i++) {
        for(int j = bi - 1; j < bi + di; j++) {
            square[i][j] = innerSquare[g][h];
            h++;
        }
        g++;
        h=0;
    }
}

public static void main(String[] args){
    //follow the image: ai = 1, bi = 2, di = 3 
    // top-left corner (ai, bi), bottom-right corner(ai + di, bi + di)
    subSquare = getInnerSquare(square, ai, bi, di);         
    subSquare = rotateMatrix(subSquare);
    replaceInnerSquare(square, subSquare, ai, bi, di);
}

这个问题还有更好的解决方案吗? 感谢!!!!

2 个答案:

答案 0 :(得分:0)

关键是观察如果你想将这个子矩阵旋转90º,你必须转置它然后恢复每一行。

#include <bits/stdc++.h>
using namespace std;

int M[7][7] = {
    {0,1,2,3,4,5,6},
    {7,8,9,10,11,12,13},
    {14,15,16,17,18,19,20},
    {21,22,23,24,25,26,27},
    {28,29,30,31,32,33,34},
    {35,36,37,38,39,40,41},
    {42,43,44,45,46,47,48}
};

void print(){
    for(int i = 0; i < 7; i++){
        for(int j = 0; j < 7; j++){
            cout<< (M[i][j] < 10? " " : "") << M[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<endl;
}

void transpose(int x0, int y0, int x1, int y1){
    int offset = 1;
    int len = x1 - x0 + 1;
    for(int i = 0; i < len; i++){
        for(int j = offset; j < len; j++){
            int t1 = j - x0, t2 = i - y0;
            swap(M[x0 + i][y0 + j],M[y0 + j - 1][x0 + i + 1]);
        }
        offset++;
    }
}

void invertLines(int x0, int y0, int x1, int y1){
    int len = x1 - x0 + 1;
    for(int i = 0; i < len; i++)
        for(int j = 0, sz = len/2; j < sz; j++)
            swap(M[x0 + i][y0 + j], M[x0 + i][y0 + len - j - 1]);
}

void rotate90(int x0, int y0, int x1, int y1){
    transpose(x0, y0, x1, y1);
    print();
    invertLines(x0, y0, x1, y1);
    print();
}



int main(){
    print();
    rotate90(1,2,4,5);
}

这应该做的工作

答案 1 :(得分:0)

Daniel的解决方案将每个元素移动两次。 在此解决方案中,每个元素仅移动一次:

x,y:广场的左上角

N:正方形的大小

void rotate(int x, int y, int N) {
    for (int i = 0; i < (N + 1) / 2; i++) {
        for (int j = 0; j < N / 2; j++) {
            int temp = M[x + i][y + j];
            M[x + i][y + j] = M[x + N - 1 - j][y + i];
            M[x + N - 1 - j][y + i] = M[x + N - 1 - i][y + N - 1 - j];
            M[x + N - 1 - i][y + N - 1 - j] = M[x + j][y + N - 1 - i];
            M[x + j][y + N - 1 - i] = temp;
        }
    }
}