左神算法基础class3—题目8之字形打印矩阵c++实现

1.题目

给定一个矩阵matrix,按照“之”字形的方式打印这个矩阵,例如:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16。“之”字形打印的结果为:1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16
【要求】 额外空间复杂度为O(1)。

在这里插入图片描述

2.分析

本题之字形输出矩阵,根据方向可分为左下到右上和从右上到左下两个方向输出,实际上可以看成斜向输出,具体方向作为bool变量更改就可以。考虑设置A,B两个点作为辅助,最开始A、B两点都在左上角位置(0,0)(0,0)位置。
(1)AB之间的连线就是需要输出的数字,每轮输出后A向右移,B向下移;
(2)使用一个bool变量表示打印的方向,每轮打印过后取逆;
(3)当A移到最右端则下移,B移到最下端则右移,直到A移到右下端结束,输出过程如下图。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.核心代码

(1)A、B点的更新

aC、bC表示列,aR、aR表示行,当aR移动到最下端结束。四个变量更新的代码可更改为使用EXP1? EXE2: EXP3可以更加简洁。

while(aR!=height)
	{
		print(arr,dir,aR,aC,bR,bC);
		if(aC < width - 1)
		{
			aC++;
		}
		else
		{
			aR++;
		}
		if(bR < height - 1)
		{
			bR++;
		}
		else
		{
			bC++;
		}
		dir = !dir;
	}

(2)打印A、B之间的数字

打印A、B之间的数字实际就是打印A、B连线上的数字每次更改一位行号和列号即可。从左往右斜向打印,打印B后,行向减一,列向加一,继续打印直到遇到A。从右往左斜向打印,打印A后,行向加一,列向减一,再继续打印直到遇到B。最开始的想法是使用中间变量记录位置,再更改中间变量找到下一个点直到完成打印,既可以打印又不会更改A、B的坐标。后来想可把这部分封装为一个函数,好处是形参不会更改实参,直接更改A、B的坐标进行打印又省去了多余的变量。

void print(int arr[][width],bool dir,int aR,int aC,int bR,int bC)
{
	if(dir)
		{
			while(bR >= aR)
			{
				cout<<arr[bR--][bC++]<<" ";
			}
		}
		else
		{
			while(aR <= bR)
			{
				cout<<arr[aR++][aC--]<<" ";
			}
		}
}

4.完整代码

#include<iostream>
#define height 4
#define width 4
using namespace std;

void print(int arr[][width],bool dir,int aR,int aC,int bR,int bC)
{
	if(dir)
		{
			while(bR >= aR)
			{
				cout<<arr[bR--][bC++]<<" ";
			}
		}
		else
		{
			while(aR <= bR)
			{
				cout<<arr[aR++][aC--]<<" ";
			}
		}
}

int main()
{
	//int arr[height][width] = {1,2,3,4,5,6,7,8,9};
	int arr[height][width] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
	int aR = 0,aC = 0,bR = 0,bC = 0;
	bool dir = true;
	
	while(aR!=height)
	{
		print(arr,dir,aR,aC,bR,bC);
		if(aC < width - 1)
		{
			aC++;
		}
		else
		{
			aR++;
		}
		if(bR < height - 1)
		{
			bR++;
		}
		else
		{
			bC++;
		}
		dir = !dir;
	}


	system("pause");
	return 0;
}

5.输出结果

在这里插入图片描述

发布了51 篇原创文章 · 获赞 1 · 访问量 1386

猜你喜欢

转载自blog.csdn.net/shi_xiao_xuan/article/details/103673365