Java n阶矩阵顺时针旋转m次问题

前言

今天参加了个笔试,就出了这道题,我最后没做出来,是真的菜。笔试结束后我自己又思考了一遍,终于实现了题目的要求

题目

题目的要求大概是这样的(有点记不住了):

  1. 先输入一个整数n,范围好像是[0, 10] 吧,所以矩阵的规格就是n * n;
  2. 每行输入n个整数,就是输入一个矩阵;
  3. 再输入一个整数m为矩阵顺时针旋转的次数,也有范围,忘了,不重要;

输入样例

3
1 2 3
4 5 6
7 8 9
4

输出样例

9 8 7
6 5 4
3 2 1

思路

题目的要求就这么多,我主要的思路是先做好一次旋转的,然后直接封装成个方法放到m次的循环里就完事了,结果我笔试那时脑抽这么简单都没想到,裂开,那么来看看一步步实现吧
首先是主函数基本框架:

public class Test {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		//输入整数 n
		int n = input.nextInt();
		int[][] arr = new int[n][n];
		//输入矩阵
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				arr[i][j] = input.nextInt();
			}
		}
		//输入 m
		int m = input.nextInt();
		//旋转 m 次
		for (int i = 0; i < m; i++) {
			 //调用旋转一次的方法
			 arr = RotateArray(arr, n);
		}
		//遍历矩阵
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				System.out.print(arr[i][j] + " ");
			}
			System.out.println();
		}
	}
}

然后就是旋转方法:
思路是传入原来的矩阵,再新建一个相同规格矩阵,用于存放旋转后的数据
把一个大矩阵分成多个环,每次旋转一个环,然后再缩小范围继续旋转
坏了,我居然不知道要怎么解释了,要不先贴个代码吧

//因为懒得new一个对象,所以直接修饰成static
public static int[][] RotateArray(int[][] arr, int n) {
	int i = 0, int j = 0; //旧矩阵起始位置
	int left = 0, rigth = n, up = 0, down = n;//规定当前范围
	int[][] rotatedArray = new int[n][n];//新建一个规格一样的矩阵
	//这个过程最好自己Debug一遍可能比较清楚,就是画圆圈,转完一层继续转下面一层,直到全部转完
	while (left < rigth-1) {
		while (j+1 < rigth) {
			rotatedArray[i][j+1] = arr[i][j];
			j++;
		}
		while (i+1 < down) {
			rotatedArray[i+1][j] = arr[i][j];
			i++;
		}
		while (j > left) {
			rotatedArray[i][j-1] = arr[i][j];
			j--;
		}
		while (i > up) {
			rotatedArray[i-1][j] = arr[i][j];
			i--;
		}
		//下次的初始位置
		i++;
		j++;
		//缩小矩阵范围
		left++;
		rigth--;
		up++;
		down--;
		//这是最后只剩下最中心一个元素的情况
		if (left == rigth-1) {
			rotatedArray[up][left] = arr[up][left];
		}
	}
	//返回旋转一次后的矩阵
	return rotatedArray;
}

类似这样,白色是下一次循环旋转部分
在这里插入图片描述

结尾

好,就这样吧,第一次写这种讲算法的博客,感觉表达得并不是很好,还请见谅,不知道还有什么更好的方法,如果有小伙伴知道可以评论或私信推荐给我,如果又不理解的也可以评论或直接私信询问

完整代码

public class Test {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int[][] arr = new int[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				arr[i][j] = input.nextInt();
			}
		}
		int m = input.nextInt();

		for (int i = 0; i < m; i++) {
			 arr = RotateArray(arr, n);
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				System.out.print(arr[i][j] + " ");
			}
			System.out.println();
		}
	}
	public static int[][] RotateArray(int[][] arr, int n) {
		int i = 0;
		int j = 0;
		int left = 0, rigth = n, up = 0, down = n;
		int[][] rotatedArray = new int[n][n];
		while (left < rigth-1) {
			while (j+1 < rigth) {
				rotatedArray[i][j+1] = arr[i][j];
				j++;
			}
			while (i+1 < down) {
				rotatedArray[i+1][j] = arr[i][j];
				i++;
			}
			while (j > left) {
				rotatedArray[i][j-1] = arr[i][j];
				j--;
			}
			while (i > up) {
				rotatedArray[i-1][j] = arr[i][j];
				i--;
			}
			i++;
			j++;
			left++;
			rigth--;
			up++;
			down--;
			if (left == rigth-1) {
				rotatedArray[up][left] = arr[up][left];
			}
		}
		return rotatedArray;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1594231563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值