递归法求螺旋矩阵(回环矩阵)

递归法求螺旋矩阵

问题描述:

给定一n维矩阵,有如下规律:
矩阵维数为1时,矩阵为:

1

矩阵维数为2时,矩阵为:

12
43

矩阵维数为3时,矩阵为:

123
894
765

矩阵维数为4时,矩阵为:

1234
1213145
1116156
10987

矩阵维数为5时,矩阵为:

12345
161718196
152425207
142322218
131211109

依次类推。。。

问题解决思路:

此题乍一看比较复杂但是我们可以观察数的规律,每一个圈中数都是从左上角顺时针依次增1,因此我们可以将此题转换成填圈从外圈填到内圈直到填满为止,那么我们接下来就以最外圈举例:
我们先从左到右将行填满,这需要我们知道左下角的元素值,我们其实可以通过数学证明出左下角的值等于左上角的值加上3*(n-1),n为外圈的行数,这样我们就可以填充了,上面一行依次加1,下面一行依次减1,然后填列,我们可以从下到上去填充,左边的列依次加1,右边的列依次减1。
这圈填完后就进入次外圈即可,依次类推。

c语言实现源代码:

#include<iostream>
using namespace std;

/**
 * function:求解螺旋矩阵
 * first:首元素(即矩阵左上角元素)的值
 * i:首元素(即矩阵左上角元素)的下标
 * n:子矩阵长度
 * m:螺旋矩阵
 */
void spiralmatrix(int first,int i, int n, int** m) {
	if (n == 1) {//n为1时,该子矩阵就一个元素,即first
		m[i][i] = first;
	}
	else if (n == 2) {//n为2时,该子矩阵首元素为first的螺旋矩阵,直接赋值即可
		m[i][i] = first;
		m[i][i + 1] = first + 1;
		m[i + 1][i + 1] = first + 2;
		m[i + 1][i] = first + 3;
	}
	/** 
	 * 当n>2时,情况比较复杂,左上角的值等于first,左下角的值等于first+3*(n-1),
	 * 然后按列补全第i行和第i+n-1行,其中第i行和第i+n-1行所有元素其中第i行是依次增1,第i+n-1行依次减1
	 * 然后再按行补齐第i列和第i+n-1列,其中第i行和第i+n-1行所有元素其中第i列是依次增1,第i+n-1列依次减1(按照从下向上填充)
	 * 最后外圈补齐后,进入内圈(利用递归法即可),这步的关键是求出左上角的元素值、左上角元素行下标、子矩阵长度
	 */
	else {
		m[i][i] = first;
		m[i + n - 1][i] = 3 * (n - 1) + first;
		for (int j = i + 1; j <= i + n - 1; j++){
			m[i + n - 1][j] = m[i + n - 1][j - 1] - 1;
			m[i][j] = m[i][j - 1] + 1;
		}
		for (int j = i + n - 2; j > i; j--) {
			m[j][i] = m[j + 1][i] + 1;
			m[j][i + n - 1] = m[j + 1][i + n - 1] - 1;
		}
		spiralmatrix(first + 4 * (n - 1), i + 1, n - 2, m);
	}
}

int main() {
	int** m;
	int n;
	cout << "请输入矩阵的维数:";
	cin >> n;
	m = new int* [n];
	for (int i = 0; i < n; i++) {
		m[i] = new int[n];
	}
	spiralmatrix(1, 0, n, m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cout << m[i][j] << "\t";
		}
		cout << "\n";
	}
	for (int i = 0; i < n; i++) {
		delete[] m[i];
	}
	delete[] m;
}

运行结果如下:

运行结果

算法复杂度分析:

不难看出此算法为O(n^2)
源代码已上传GitHub,请点击获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值