• + 0 comments

    Concise C++, one-pass, O(m * n).

    Only 1 integer division per ring. Lots of branching in the inner loop but CPU branch prediction should kick in quite nicely on larger matrices.

    void matrixRotation(vector<vector<int>> matrix, int rot) {
        int hei = matrix.size(), wid = matrix[0].size(), rings = (1+min(hei, wid)) >> 1;
        int map[hei][wid];
        memset(map, 0, sizeof(map));
    
        for (int r=0, rh=hei-1, rw=wid-1; r<rings; r++, rh-=2, rw-=2) {
            int c2=rh+rw, c3=c2+rw, c4=c3+rh;
    
            for (int dof=0, sof=rot % c4, dx=0, dy=0, sx, sy; dof<c4; dof++, sof++) {
                if (sof >= c4) sof -= c4;
                if (sof < rw) sx=sof, sy=0; else
                if (sof < c2) sx=rw, sy=sof-rw; else
                if (sof < c3) sx=c3-sof, sy=rh; else
                    sx=0, sy=c4-sof;
    
                map[r+dy][r+dx] = matrix[r+sy][r+sx];
    
                if (dof < rw) dx++; else if (dof < c2) dy++; else if (dof < c3) dx--; else dy--;
            }
        }
    
        for (int x,y=0; y<hei; y++) {
            for (x=0; x<wid; x++) cout << map[y][x] << " ";
            cout << "\n";
        }
    }