[面试金典]顺时针打印矩阵

来源:互联网 发布:让其响彻动作数据密码 编辑:程序博客网 时间:2024/05/21 14:00

题目链接:http://www.nowcoder.com/practice/9b4c81a02cd34f76be2659fa0d54342a?rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

问题

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:

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;    }};

反思

迷宫问题是一个常见的问题,其思想还是很不错的。

0 0
原创粉丝点击