• 剑指OFFER 顺时针打印矩阵


    剑指OFFER 顺时针打印矩阵

    试错记录

    递归解(代码有错)

    class Solution {
    public:
        vector<int> res;
        void printSuround(vector<vector<int>> &m,int x,int y)
        {
            int size = m.size();
            if(m[x][y]==-1)return;
            while(x>=0 && y>=0 && x<size && y<size && m[x][y]!=-1)
            {
                res.push_back(m[x][y]);
                m[x][y]=-1;
                y++;
            }
            y--;
            x++;
            while(x>=0 && y>=0 && x<size && y<size && m[x][y]!=-1)
            {
                res.push_back(m[x][y]);
                m[x][y]=-1;
                x++;
            }
            x--;
            y--;
            while(x>=0 && y>=0 && x<size && y<size && m[x][y]!=-1)
            {
                res.push_back(m[x][y]);
                m[x][y]=-1;
                y--;
            }
            y++;
            x--;
            while(x>=0 && y>=0 && x<size && y<size && m[x][y]!=-1)
            {
                res.push_back(m[x][y]);
                m[x][y]=-1;
                x--;
            }
            x++;
            y++;
            printSuround(m,x,y);
        }
    
        vector<int> printMatrix(vector<vector<int>> matrix) {
            res.clear();
            if(matrix.size() == 0)return res;//如果矩阵空则返回一个空vector
            printSuround(matrix,0,0);
            return res;
        }
    };
    

    循环解(代码有错)

    不使用递归,转换为循环,仍超时... 懵了

    class Solution {
    public:
        vector<int> res;
        pair<int,int> fac[4] = {{0,1},{1,0},{0,-1},{-1,0}};
    
        vector<int> printMatrix(vector<vector<int>> m) {
            res.clear();
            if(m.size() == 0)return res;//如果矩阵空则返回一个空vector
            if(m.size() == 1)
            {
                res.push_back(m[0][0]);
                return res;
            }
            int x = 0;
            int y = 0;
            int size = m.size();
            while(m[x][y] != -1)
            {
                for(int i=0;i<4;i++)
                {
                    while(x>=0 && y>=0 && x<size && y<size && m[x][y] != -1)
                    {
                        res.push_back(m[x][y]);
                        m[x][y] = -1;
                        x += fac[i].first;
                        y += fac[i].second;
                    }
                    x -= fac[i].first;
                    y -= fac[i].second;
                    x += fac[(i+1)%4].first;
                    y += fac[(i+1)%4].second;
                }
            }
            return res;
        }
    };
    

    现在还没弄明白是哪个步骤这么耗时,复杂度应该是差不多,先放这,以后弄明了再补充

    找出原因

    算法的思路实际并没有问题,而是因为考虑少了一些特殊情况

    出现超时其实是因为 当只输入单行或者单列时候出现了死循环(数组越界访问)

    解决办法:

    • 在大while里面再次限制x,y的值,当旋转一周后,仍然没有矩阵元素可加入res数组中就直接结束,不再继续旋转(继续旋转可能会使得访问越界)

    • 前面的代码是使用-1来标记元素是否被访问过(这种方式有缺陷,如果矩阵的元素本身有-1存在就会混淆判断),下面改用了哈希表,在避免混淆的同时避免重复访问vector数组,效率得到了很大提升,相同的代码在leetcode上提交,运行速度简直恐怖.

      题目 54.Spiral Matrix
      Runtime: 0 ms, faster than 100.00% of C++ online submissions for Spiral Matrix.
      Memory Usage: 8.8 MB, less than 24.24% of C++ online submissions for Spiral Matrix.
      

    下面给出正确代码:

    class Solution {
    public:
        vector<int> res;
        pair<int,int> fac[4] = {{0,1},{1,0},{0,-1},{-1,0}};//旋转因子
        map<pair<int,int>,bool> hash;
        vector<int> printMatrix(vector<vector<int>> m) {
            res.clear();
            if(m.size() == 0)return res;//如果矩阵空则返回一个空vector
    
            int x = 0;
            int y = 0;
            int x_size = m.size();//行数
            int y_size = m[0].size();//列数
            //这里存在短路,前面条件不满足就不查哈希表了
            while(x>=0 && y>=0 && x<x_size && y<y_size && !hash[pair<int,int>(x,y)])
            {
                for(int i=0;i<4;i++)//四个方向,旋转四次
                {
                    //这里存在短路,前面条件不满足就不查哈希表了
                    while(x>=0 && y>=0 && x<x_size && y<y_size && !hash[pair<int,int>(x,y)])
                    {
                        res.push_back(m[x][y]);
                        hash[pair<int,int>(x,y)] = true;
                        x += fac[i].first;
                        y += fac[i].second;
                    }
                    x -= fac[i].first;
                    y -= fac[i].second;//越界返回
                    x += fac[(i+1)%4].first;
                    y += fac[(i+1)%4].second;//前往下一个元素
                }
            }
            return res;
        }
    };
    

    其他题解

    下面代码不是我写的,学习一下别人是怎么写的

    从代码上看效率,不管是空间复杂度还是时间复杂度都是比较好的.但是逻辑需要很清晰才能写出来

    class Solution {
    public:
        vector<int> printMatrix(vector<vector<int>> matrix) {
            int row=matrix.size();
            int col=matrix[0].size();
            vector<int> result;
            if(row==0||col==0)
                return result;
            int left=0,right=col-1,top=0,btm=row-1;
            while(left<=right&&top<=btm)
                {
                for(int i=left;i<=right;i++)
                    result.push_back(matrix[top][i]);
                if(top<btm)
                    for(int i=top+1;i<=btm;i++)
                        result.push_back(matrix[i][right]);
                if(top<btm&&left<right)
                    for(int i=right-1;i>=left;i--)
                        result.push_back(matrix[btm][i]);
                if(top+1<btm&&left<right)
                    for(int i=btm-1;i>=top+1;i--)
                        result.push_back(matrix[i][left]);
                left++;right--;top++;btm--;
            }
            return result;
        }
    };
    
  • 相关阅读:
    16年青岛网络赛 1001 I Count Two Three
    最短路算法--模板
    POJ 1511 Invitation Cards (spfa的邻接表)
    POJ 2240 Arbitrage
    POJ 1502 MPI Maelstrom
    POJ 1860 Currency Exchange (最短路)
    最短路径--SPFA 算法
    POJ 3660 Cow Contest
    POJ 3259 Wormholes (Bellman_ford算法)
    POJ 3268 Silver Cow Party (双向dijkstra)
  • 原文地址:https://www.cnblogs.com/virgildevil/p/12188733.html
Copyright © 2020-2023  润新知