题目描述:
对于一个矩阵,请设计一个算法从左上角(mat[0][0])开始,顺时针打印矩阵元素。
给定int矩阵mat,以及它的维数nxm,请返回一个数组,数组中的元素为矩阵元素的顺时针输出。
测试样例:
[[1,2],[3,4]],2,2
返回:[1,2,4,3]
题目解析:
将问题分解为一下几个步骤:
1)从左到右打印矩阵
2)从上到下打印矩阵
3)从右到左打印矩阵
4)从下到上打印矩阵
执行完这些,打印完矩阵的一圈,再次循环,其中要注意边界条件,这里非常容易出错。
class Printer {
public:
vector<int> clockwisePrint(vector<vector<int> > mat, int n, int m) {
vector<int> res;
if(mat.empty())
return res;
int startX = 0,startY = 0;
int endX = n-1, endY = m-1;
int i = 0,j = 0;
while(startX <= endX && startY <= endY)
{
//从左向右打印,i=startX不变,j变化
for(j = startY;j <= endY;j++)
res.push_back(mat[i][j]);
j--; //此时j=endY+1
//从上到下打印,j=endY,i变化
for(i = startX+1;i <= endX;i++)
res.push_back(mat[i][j]);
i--;
//从右向左打印,i=endX,j变化
//当只有一行时,startX=endX,只执行从左到右的代码,否则会重复
for(j = endY-1;j >= startY && startX < endX;j--)
res.push_back(mat[i][j]);
j++;
//从下向上打印,j=startY,i变化,
//当只有一列时,startY=endY,只执行从上到下的代码,否则会重复
for(i = endX-1;i > startX && startY < endY;i--)
res.push_back(mat[i][j]);
i++;
//走完一圈之后,重置一下
startX++,endX--;
startY++,endY--;
}
return res;
}
};
每次push_back的时候,如果用mat[i][j]控制,很容易忘记最后++或--,所以可以使用startX,startY,endX,endY来控制。
class Printer {
public:
vector<int> clockwisePrint(vector<vector<int> > mat, int n, int m) {
// write code here
vector<int> res;
if(mat.empty())
return res;
int startX = 0,endX = n-1;
int startY = 0,endY = m-1;
int i = 0,j = 0;
while(startX <= endX && startY <= endY)
{
//从左向右打印,i=startX不变,j变化
for(j = startY;j <= endY;j++)
res.push_back(mat[startX][j]);
//从上到下打印,j=endY,i变化
for(i = startX+1;i <= endX;i++)
res.push_back(mat[i][endY]);
//从右向左打印,i=endX,j变化
//当只有一行时,只让从左到右执行一次,此处不执行
for(j = endY-1;j >= startY && startX < endX;j--)
res.push_back(mat[endX][j]);
//从下向上打印,j=startY,i变化,
//当只有一列时,只让从上到下执行一次,此处不执行
for(i = endX-1;i > startX && startY < endY;i--)
res.push_back(mat[i][startY]);
//走完一圈之后,重置一下
startX++,endX--;
startY++,endY--;
}
return res;
}
};
(*^▽^*)