面试题29-顺时针打印矩阵

题目

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
面试题29-顺时针打印矩阵_第1张图片
则依次打印出数组:1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10。

解题思路

我们不用vector,就用基本的二维数组。
当我们遇到一个复杂问题的时候,可以用图形来帮助思考。由于是从外圈到内圈的顺序依次打印的,所以我们可以把矩阵想象成若干个圆。我们可以用一个循环来打印矩阵,每次打印矩阵中的一个圆。假设这个矩阵的行数rows,列数是columns。打印第一圈的左上角的坐标是(0,0),第二圈的左上角的坐标是(1,1),以此类推。我们注意到,左上角的坐标中行标和列标总是相同的,于是可以在矩阵中选取左上角为(start,start)的一圈作为我们分析的目标。
循环结束的条件经过归纳论证为columns>start*2并且rows>start*2(不太懂)。所以我们可以用如下的循环来打印矩阵:

void PrintMatrixClockwisely(int**numbers, int columns, int rows)
	{
     
		if (!numbers || columns <= 0 || rows <= 0)
			return;
		int start = 0;
		while (columns > start * 2 && rows > start * 2)
		{
     
			PrintMatrixInCircle(numbers, columns, rows, start);
			++start;
		}
	}

接着就是打印一圈

void PrintMatrixInCircle(int **numbers, int columns,int rows, int start)
	{
     
		int endX = columns - 1 - start; //列数
		int endY = rows - 1 - start;//行数
		//从左到右打印一行
		for (int i = start; i <=endX; ++i)
		{
     
			cout<<(numbers[start][i])<<" ";
		}
		//从上到下打印一列
		if (start < endY)
		{
     
			for (int i = start + 1; i <= endY; ++i)
			{
     
				cout << (numbers[i][endX]) << " ";
			}
		}
		//从右到左打印一行
		if (start < endY&&start<endX)
		{
     
			for (int i = endX - 1; i>=start; --i)
			{
     
				cout << (numbers[endY][i]) << " ";
			}
		}
		//从下到上打印一列
		if (start < endY-1&&start < endX)
		{
     
			for (int i = endY - 1; i >= start+1; --i)
			{
     
				cout << (numbers[i][start]) << " ";
			}
		}
		
	}

C++实现

class Solution
{
     
public:
	void PrintMatrixClockwisely(int**numbers, int columns, int rows)
	{
     
		if (!numbers || columns <= 0 || rows <= 0)
			return;
		int start = 0;
		while (columns > start * 2 && rows > start * 2)
		{
     
			PrintMatrixInCircle(numbers, columns, rows, start);
			++start;
		}
	}
	void PrintMatrixInCircle(int **numbers, int columns,int rows, int start)
	{
     
		int endX = columns - 1 - start; //右下角的横坐标,实质是剩余的未打印矩阵的列数
		int endY = rows - 1 - start;//右下角的纵坐标,实质是剩余的未打印矩阵的行数
		//从左到右打印一行
		for (int i = start; i <=endX; ++i)
		{
     
			cout<<(numbers[start][i])<<" ";
		}
		//从上到下打印一列
		if (start < endY)
		{
     
			for (int i = start + 1; i <= endY; ++i)
			{
     
				cout << (numbers[i][endX]) << " ";
			}
		}
		//从右到左打印一行
		if (start < endY&&start<endX)
		{
     
			for (int i = endX - 1; i>=start; --i)
			{
     
				cout << (numbers[endY][i]) << " ";
			}
		}
		//从下到上打印一列
		if (start < endY-1&&start < endX)
		{
     
			for (int i = endY - 1; i >= start+1; --i)
			{
     
				cout << (numbers[i][start]) << " ";
			}
		}		
	}
};
//测试用例
int main()
{
     
	//int nums[][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16} };
	int row = 4, column = 4;
	int ** array = (int**)malloc(sizeof(int*)*row);
	int i, j;
	int add = 1;
	for (i = 0; i < row; i++)
	{
     
		array[i] = (int*)malloc(sizeof(int)*column);
		for (j = 0; j < column; j++)
		{
     
			array[i][j] = add++;	
		}
	}
	Solution s;
	s.PrintMatrixClockwisely(array,4,4);
	system("pause");
	return 0;
}

复杂度分析

  1. 时间复杂度:O(N),N为矩阵元素的个数
  2. 空间复杂度:O(1)

测试用例

数组中有多行多列;数组中只有一行;数组中只有一列;数组中只有一行一列。

你可能感兴趣的:(数组,二叉树,链表,数据结构)