题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
1、思路1:可以将上下左右四个范围设定,通过改变上下左右四个界限,实现顺时针打印。
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
//行数row
int row = matrix.size();
//列数col
int col = matrix[0].size();
vector<int> res;
if(row == 0 && col == 0)
return res;
//初始元素的行为0
int leftTop = 0;
//右上角的元素的列
int rightTop = col - 1;
//初始元素的列为0
int leftBottom = 0;
//右下角的元素的行
int rightBottom = row - 1;
while(leftTop<=rightTop && leftBottom<=rightBottom)
{
for(int i=leftTop; i <= rightTop; i++)
res.push_back(matrix[leftTop][i]);
for(int i = leftTop + 1; i <= rightBottom; i++)
res.push_back(matrix[i][rightTop]);
//如果leftTop=rightBottom,就不需要执行下面的步骤了
if(leftTop != rightBottom)
for(int i = rightTop-1;i >= leftTop;i --)
res.push_back(matrix[rightBottom][i]);
if(rightTop != leftBottom)
for(int i = rightBottom-1; i > leftTop; i--)
res.push_back(matrix[i][leftBottom]);
leftTop++; leftBottom++;
rightTop--; rightBottom--;
}
return res;
}
};
2、书上的思路:左上角的左上角的左边中行标和列标总是相同的,于是可以在矩阵中选取左上角为(start,end)的一圈作为分析目标。其循环继续的条件是columns>startX×2并且rows>startY×2.
运行出现错误:
class Solution {
public:
void printMatrix(int** matrix,int columns,int rows) {
//int columns = matrix[0].size();
//int rows = matrix.size();
if(matrix == nullptr || columns<=0 || rows<=0)
return;
int start = 0;
while(columns>start*2 && rows>start*2){
PrintMatrixInCircle(matrix,columns,rows,start);
start++;
}
}
void PrintMatrixInCircle(int** matrix,int columns,int rows,int start){
int endX=columns-1-start;
int endY=rows-1-start;
//从左到右打印
for(int i=start;i<=endY;i++){
int number = matrix[start][i];
printNumber(number);
}
//从上到下打印
if(start<endY){
for(int i=start+1;i<=endX;i++){
int number = matrix[i][endX];
printNumber(number);
}
}
//从右到左打印
if(start<endX&&start<endY){
for(int i=endX-1;i>=start;i--){
int number = matrix[endY][i];
printNumber(number);
}
}
//从下到上打印
if(start<endX&&start<endY-1){
for(int i=endY-1;i>start;i--){
int number = matrix[i][start];
printNumber(number);
}
}
}
void printNumber(int number)
{
printf("%d\t", number);
}
};
3、将二者结合:因为每一次循环开始左上角的坐标中行标和列标总是相等,所以令leftTop=leftBottom=start=0;rightTop=endY=col-1-start; rightBottom=endX=row-1-start;
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
//行数row
int row = matrix.size();
//列数col
int col = matrix[0].size();
vector<int> res;
if(row == 0 && col == 0)
return res;
//初始元素行标和列标相同均为0
int start = 0;
while(col>start*2 && row>start*2){
//右上角的元素的列
int endY = col - 1 -start;
//初始元素的列为0
int endX = row - 1 -start;
//从左到右打印
for(int i=start; i <= endY; i++)
res.push_back(matrix[start][i]);
//从上到下打印,第二步的前提条件是:终止行数大于起始行数
if(start<endX){
for(int i = start + 1; i <= endX; i++)
res.push_back(matrix[i][endY]);}
//第三步打印的前提条件是圈内至少两行两列,所以要求终止行数大于起始行数,终止列数大于起始列数
if(start <endX && start<endY){
for(int i = endY-1;i >= start;i--)
res.push_back(matrix[endX][i]);}
//需要第四步的条件是三行两列(两行两列就不需要了,第三步已经打印完成了),所以终止行号比起始行号至少大2,终止列号大于起始列号
if(start<endY && start<endX-1){
for(int i = endX-1; i > start; i--)
res.push_back(matrix[i][start]);}
start++;
}
return res;
}
};