HackerRank [Algo] Matrix Rotation

10 篇文章 0 订阅
7 篇文章 0 订阅

原题网址:https://www.hackerrank.com/challenges/matrix-rotation-algo

You are given a 2D matrix, a, of dimension MxN and a positive integer R. You have to rotate the matrix R times and print the resultant matrix. Rotation should be in anti-clockwise direction.

Rotation of a 4x5 matrix is represented by the following figure. Note that in one rotation, you have to shift elements by one step only (refer sample tests for more clarity).

matrix-rotation

It is guaranteed that the minimum of M and N will be even.

Input Format 
First line contains three space separated integers, MN and R, where M is the number of rows, N is number of columns in matrix, and R is the number of times the matrix has to be rotated. 
Then M lines follow, where each line contains N space separated positive integers. These M lines represent the matrix.

Output Format 
Print the rotated matrix.

Constraints 
2 <= MN <= 300 
1 <= R <= 109 
min(M, N) % 2 == 0 
1 <= aij <= 108, where i ∈ [1..M] & j ∈ [1..N]

Sample Input #00

4 4 1
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

Sample Output #00

2 3 4 8
1 7 11 12
5 6 10 16
9 13 14 15

Sample Input #01

4 4 2
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

Sample Output #01

3 4 8 12
2 11 10 16
1 7 6 15
5 9 13 14

Sample Input #02

5 4 7
1 2 3 4
7 8 9 10
13 14 15 16
19 20 21 22
25 26 27 28

Sample Output #02

28 27 26 25
22 9 15 19
16 8 21 13
10 14 20 7
4 3 2 1

Sample Input #03

2 2 3
1 1
1 1

Sample Output #03

1 1
1 1

Explanation 
Sample Case #00: Here is an illustration of what happens when the matrix is rotated once.

 1  2  3  4      2  3  4  8
 5  6  7  8      1  7 11 12
 9 10 11 12  ->  5  6 10 16
13 14 15 16      9 13 14 15

Sample Case #01: Here is what happens when to the matrix after two rotations.

 1  2  3  4      2  3  4  8      3  4  8 12
 5  6  7  8      1  7 11 12      2 11 10 16
 9 10 11 12  ->  5  6 10 16  ->  1  7  6 15
13 14 15 16      9 13 14 15      5  9 13 14

Sample Case #02: Following are the intermediate states.

1  2  3  4      2  3  4 10    3  4 10 16    4 10 16 22
7  8  9 10      1  9 15 16    2 15 21 22    3 21 20 28
13 14 15 16 ->  7  8 21 22 -> 1  9 20 28 -> 2 15 14 27 ->
19 20 21 22    13 14 20 28    7  8 14 27    1  9  8 26
25 26 27 28    19 25 26 27    13 19 25 26   7 13 19 25



10 16 22 28    16 22 28 27    22 28 27 26    28 27 26 25
 4 20 14 27    10 14  8 26    16  8  9 25    22  9 15 19
 3 21  8 26 ->  4 20  9 25 -> 10 14 15 19 -> 16  8 21 13
 2 15  9 25     3 21 15 19     4 20 21 13    10 14 20  7
 1  7 13 19     2  1  7 13     3  2  1  7     4  3  2  1

Sample Case #03: As all elements are same, any rotation will reflect the same matrix.


方法:与一维数组平移相同,只需要将一维坐标映射到二维。

import java.io.*;
import java.util.*;

public class Solution {
    
    private static int getY(int left, int top, int right, int bottom, int pos) {
        if (pos < bottom - top) return top + pos;
        if (pos < bottom - top + right - left) return bottom;
        if (pos < (bottom - top) * 2 + right - left) return top + ((bottom - top) * 2 + (right - left)) - pos;
        return top;        
    }
    
    private static int getX(int left, int top, int right, int bottom, int pos) {
        if (pos < bottom - top) return left;
        if (pos < bottom - top + right - left) return left +  pos - (bottom - top);
        if (pos < (bottom - top) * 2 + right - left) return right;
        return right - (pos - ((bottom - top) * 2 + (right - left)));
    }
    
    private static void reverse(int[][] matrix, int left, int top, int right, int bottom, int from, int to) {
        for(int i = from, j = to; i < j; i++, j--) {
            int iy = getY(left, top, right, bottom, i);
            int ix = getX(left, top, right, bottom, i);
            int jy = getY(left, top, right, bottom, j);
            int jx = getX(left, top, right, bottom, j);
            int t = matrix[iy][ix];
            matrix[iy][ix] = matrix[jy][jx];
            matrix[jy][jx] = t;
        }
    }
    
    private static void rotate(int[][] matrix, int left, int top, int right, int bottom, int rotate) {
        int length = (right - left) * 2 + (bottom - top) * 2;
        rotate %= length;
        if (rotate == 0) return;
        reverse(matrix, left, top, right, bottom, 0, length - 1 - rotate);
        reverse(matrix, left, top, right, bottom, length - rotate, length - 1);
        reverse(matrix, left, top, right, bottom, 0, length - 1);        
    }

    public static void main(String[] args) {
        /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
        Scanner scanner = new Scanner(System.in);
        int m = scanner.nextInt();
        int n = scanner.nextInt();
        int r = scanner.nextInt();
        int[][] matrix = new int[m][n];
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                matrix[i][j] = scanner.nextInt();
            }
        }
        int left = 0, top = 0, right = n - 1, bottom = m - 1;
        while (left < right && top < bottom) {
            rotate(matrix, left, top, right, bottom, r);
            left++;
            top++;
            right--;
            bottom--;
        }
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if (j > 0) System.out.print(" ");
                System.out.print(matrix[i][j]);
            }
            System.out.println();
        }
    }
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值