问题
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
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.
分析
一开始把他当做迷宫问题处理,假如碰到边界或者访问过的点,就按照→, ↓, ←, ↑的顺序依次变向,直到周围的四个方向的点都是访问过的为止。
- 边界的判断:0~size
- 访问过的点:用一个矩阵来记录
- 四个方向:{→, ↓, ←, ↑} = {{0,1}, {1,0}, {0, -1}, {-1, 0}}
然而杯具的是OJ结果是栈溢出,说白点就是我用的空间太大了。纠结蛋疼之际只能改变一下判断方法,剩下记录访问点的矩阵空间。方法就是记录访问边界
- 初始化:横纵坐标的访问方位是{横坐标, 纵坐标} = {{0, size},{0, size}}
- 访问了第一行后:纵坐标范围缩小为{横坐标, 纵坐标} = {{0, size},{1, size}}
- 访问了最后一列后:横坐标范围缩小为{横坐标, 纵坐标} = {{0, size - 1},{1, size}}
- 依次循环记录…
这样用一个2*2的数据就可以代替一个矩阵了,太棒了!
小结
又学会了一项优化技能;其次是二维vector的初始化方法:
vector <vector<int> > hey(m, vector <int>(n, 0));
实现
方案一
class Solution {
public:
bool check(vector <vector <bool> > m, int x, int y, int dx, int dy){
int lx = m[0].size() - 1;
int ly = m.size() - 1;
if(x + dx < 0 || x + dx > lx || y + dy < 0 || y + dy > ly){
return false;
}
if(m[x + dx][y + dy]){
return false;
}
return true;
}
vector<int> printMatrix(vector<vector<int> > matrix) {
vector <int> rv;
if(matrix.empty())
return rv;
int m = matrix.size();
int n = matrix[0].size();
vector <vector <bool> > fv(m, vector<bool>(n, false));
int dy[4] = {1, 0, -1, 0};
int dx[4] = {0, 1, 0, -1};
bool flag = true;
int i = 0, j = 0;
rv.push_back(matrix[0][0]);
fv[0][0] = true;
//int T = m * n - 1;
while(flag){
flag = false;
for(int k = 0; k < 4; k++){
while(check(fv, i, j, dx[k], dy[k])){
flag = true;
i += dx[k];
j += dy[k];
rv.push_back(matrix[i][j]);
fv[i][j] = true;
}
}
}
return rv;
}
};
方案二
class Solution {
public:
bool check(int m[2][2], int x, int y, int dx, int dy){
if(x + dx < m[0][0] || x + dx > m[0][1] || y + dy < m[1][0] || y + dy > m[1][1]){
return false;
}
return true;
}
vector<int> printMatrix(vector<vector<int> > matrix) {
vector <int> rv;
if(matrix.size() == 0 || matrix[0].size() == 0)
return rv;
int max[2][2] = {{0, 0}, {0, 0}};
max[0][1] = matrix.size() - 1;
max[1][1] = matrix[0].size() - 1;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
bool flag = true;
int i = 0, j = 0;
rv.push_back(matrix[0][0]);
while(flag){
flag = false;
for(int k = 0; k < 4; k++){
while(check(max, i, j, dx[k], dy[k])){
flag = true;
i += dx[k];
j += dy[k];
rv.push_back(matrix[i][j]);
}
switch (k) {
case 0:
max[0][0] += 1;
break;
case 1:
max[1][1] -= 1;
break;
case 2:
max[0][1] -= 1;
break;
case 3:
max[1][0] += 1;
break;
default:
break;
}
}
}
return rv;
}
};
反思
迷宫问题是一个常见的问题,其思想还是很不错的。