题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
思路:
1、二维数组的行列数,row,col
2、特殊测试用例判断
3、每圈对应的左上角坐标(start,start),从而分析循环继续的条件
col>startX*2 && row>startY*2,,,,,,,,,,,,,,,,,,,,,,startX=startY=start
打印第一圈的左上角坐标是(0,0),第二圈的左上角坐标(1,1),依此类推得到每圈的左上角坐标行标和列表总是相同的,于是取左上角(start,start)的一圈作为分析目标;
对于一个5*5矩阵,最后一圈只有1个数字,对应的左上角坐标为(2,2),发现5>2*2;
对于一个6*6矩阵,最后一圈只有4个数字,对应的左上角坐标为(2,2),发现6>2*2;
对于一个7*8矩阵,最后一圈只有1个数字,对应的左上角坐标为(3,3),发现8>3*2, 7>3*2;
4、如何实现打印一圈呢?对应的start++, 其中,用容器存储遍历的元素res.push_back
找出每圈对应的右下角坐标(endX,endY);
顺时针打印:注意边界
//从左到右打印一行
//从上到下打印一列+ 判断条件(纵坐标start小于endY)
//从右到左打印一行+ 判断条件(横坐标start小于endX,纵坐标start小于endY)
//从下到上打印一列+ 判断条件(横坐标start小于endX,纵坐标start小于endY-1)
5、利用vector的二维数组初始化,resize()
vector<vector <int> > matrix(3);//3行一维数组
for (int i = 0; i < 3; i++)
matrix[i].resize(5);//每一维有5个元素,即3行5列数组
//法一:有子函数
#include<iostream>
#include<vector>
#include<iomanip> //左对齐包含的头文件
using namespace std;
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix)
{
//二维数组的行列数
int row = matrix.size();//行
int col = matrix[0].size();//列
vector<int>res;
//特殊测试用例判断
if(row <= 0 || col <= 0)
return res;
res.clear();
int start = 0;
while (col > start * 2 && row > start * 2)
{
res=PrintMatrixInCircle(matrix, col, row, start, res);
++start;
}
return res;
}
//把矩阵想象成若干个圈,顺时针循环打印矩阵中的每个圈
vector<int> PrintMatrixInCircle(vector<vector<int> > matrix, int col, int row, int start, vector<int>res)
{
int endX = col - 1 - start;//列
int endY = row - 1 - start;//行
//从左到右打印一行
for (int i = start; i <= endX; i++)
res.push_back(matrix[start][i]);
//从上到下打印一列+ 判断条件
if (start < endY) //纵坐标start小于endY
{
for (int i = start + 1; i <= endY; i++)
res.push_back(matrix[i][endX]);
}
//从右到左打印一行+ 判断条件
if (start < endX && start < endY)//横坐标start小于endX,纵坐标start小于endY
{
for (int i = endX - 1; i >= start; i--)
res.push_back(matrix[endY][i]);
}
//从下到上打印一列+ 判断条件
if (start < endX&&start < endY - 1)//横坐标start小于endX,纵坐标start小于endY-1
{
for (int i = endY - 1; i >= start + 1; i--)
res.push_back(matrix[i][start]);
}
return res;
}
};
//主函数
void main()
{
Solution *s = new Solution;
//vector<vector <int> > matrix(4, vector<int>(4,1));//m*n的二维vector,注意两个 "> "之间要有空格!
vector<vector <int> > matrix(3);//3行一维数组
for (int i = 0; i < 3; i++)
matrix[i].resize(5);//每一维有5个元素,即3行5列
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
matrix[i][j] = (i + 1)*(j + 1);
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
cout <<left<< setw(3) <<matrix[i][j]<<" ";//左对齐输出矩阵
cout << endl;
}
vector<int>result;
result = s->printMatrix(matrix);
cout << "顺时针打印的矩阵为:" << endl;
for (auto i : result)
cout << i << " ";
cout << endl;
}
//方法二:写在一个函数里
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix)
{
//二维数组的行列数
int row = matrix.size();//行
int col = matrix[0].size();//列
vector<int>res;
//特殊测试用例判断
if (row <= 0 || col <= 0)
return res;
int start = 0;//左上角坐标(start,start),(0,0),(1,1),(2,2)...
while (col > start * 2 && row > start * 2)
{
//每圈对应的右下角坐标
int endX = col - 1 - start;//列
int endY = row - 1 - start;//行
//从左到右打印一行
for (int i = start; i <= endX; i++)
res.push_back(matrix[start][i]);
//从上到下打印一列+ 判断条件
if (start < endY)
{
for (int i = start + 1; i <= endY; i++)
res.push_back(matrix[i][endX]);
}
//从右到左打印一行+ 判断条件
if (start < endX && start < endY)
{
for (int i = endX - 1; i >= start; i--)
res.push_back(matrix[endY][i]);
}
//从下到上打印一列+ 判断条件
if (start < endX && start < endY - 1)
{
for (int i = endY - 1; i >= start + 1; i--)
res.push_back(matrix[i][start]);
}
++start;
}
return res;
}
};