剑指offer 刷了这么多题但是这一道,这个算法和其他人的算法都不一样 ,必须吹爆,
题目描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 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.
解题思路
把题目给出的矩阵看成一个二维平面, 顺时针打印 就是顺时针走过二维平面,从轨迹上来看可以知道,当走到边界时,对走方向进行判断(优先级为上 ,右 ,下 ,左 ,即能上就不上 , 不上就右),上 ,右不通 , 左走过 , 只能下 ,就向下走
当下走到底时,同理,只能向左 ,
然后问题就出现在向做一步走的时候 , 走了一步后,由于优先级是先上,此时就会向上走,导致样例不通过。
所以使用last 变量 来记录 上一次的方向 , 且上一次方向优先级最高 。
代码实现
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
//最直观的做法就是按照题目要求,遍历矩阵的边界,首先我们可以看出遍历到边界的时候,是向右遍历。
//
vector<int>res;
int row = 0 , col = 0;
const int mt_row = matrix.size();
const int mt_col = matrix[0].size();
int last = 10; //存储上次的方向 第一次就是右边
int ** mt = (int **)malloc(sizeof(int*)*mt_row); //记录路程
for(int i = 0 ; i < mt_row ; i++){
*(mt+i) = (int *)malloc(sizeof(int)*mt_col);
memset(*(mt+i),0,sizeof(int)*mt_col);
}
res.push_back(matrix[row][col]);
mt[row][col] = 1;
while(direct(mt,row ,col,mt_row,mt_col,last)!=0){
res.push_back(matrix[row][col]);
}
return res;
}
int direct(int ** mt,int & row ,int & col,const int mt_row , int mt_col ,int & last) // 0 表示结束 (0,1) 1 表示下 ,(0,-1)-1 表示上 ,(1,0) 10 表示右边 , (-1,0)-10 表示左边
{
switch (last){
case 1:
if(row +1 < mt_row && mt[row+1][col]!=1) //向下延展
{
mt[++row][col] = 1;
return 1;
}
break;
case -1:
if(row-1>=0 && mt[row-1][col] != 1) //向上延展
{
mt[--row][col] = 1;
return -1;
}
break;
case 10:
if(col + 1< mt_col && mt[row][col+1]!=1) //向右延展
{
mt[row][++col] = 1;
return 10;
}
break;
case -10:
if(col -1 >= 0 && mt[row][col-1] != 1) //向左延展
{
mt[row][--col] = 1;
return -10;
}
break;
}
//顺序即为优先级
if(row-1>=0 && mt[row-1][col] != 1) //向上延展
{
mt[--row][col] = 1;
last = -1;
return -1;
}
if(col + 1< mt_col && mt[row][col+1]!=1) //向右延展
{
mt[row][++col] = 1;
last = 10;
return 10;
}
if(row +1 < mt_row && mt[row+1][col]!=1) //向下延展
{
mt[++row][col] = 1;
last = 1;
return 1;
}
if(col -1 >= 0 && mt[row][col-1] != 1) //向左延展
{
mt[row][--col] = 1;
last = -10;
return -10;
}
return 0;
}
};
引申
这个代码不仅能实现顺时针, 同样还可以逆时针,甚至X型 S型 都可以实现,前两者只需要对direct 函数进行优先级的调整 ,后者需要增加新的方向。