• 面试题29.顺时针打印矩阵


    image-20200606122713224

    模拟+记录路径

    思路

    • 模拟矩阵打印的路径,同时用数组record记录当前元素是否被访问过
    • 注意边界处理,否则易越界。

    代码

        /**
         * 2ms O(mn)
         * 空间复杂度 O(mn)
         */
        public static int[] spiralOrder(int[][] matrix) {
            if(matrix==null||matrix.length==0) return new int[0];
            int r = matrix.length,count=0,c = matrix[0].length,sum=r*c;
            int[] ans=new int[sum];
            int[][] record= new int[r][c];
            int i=0,j=0;
            while(count<sum){
                while(j<c&&record[i][j]==0){
                    ans[count]=matrix[i][j];
                    record[i][j]=1;
                    count++;
                    j++;
                }
                j--;
                i++;
    
                while(i<r&&record[i][j]==0){
                    ans[count]=matrix[i][j];
                    record[i][j]=1;
                    count++;
                    i++;
                }
                i--;
                j--;
    
                while(j>=0&&record[i][j]==0){
                    ans[count]=matrix[i][j];
                    record[i][j]=1;
                    count++;
                    j--;
                }
                j++;
                i--;
    
                while(i>=0&&record[i][j]==0){
                    ans[count]=matrix[i][j];
                    record[i][j]=1;
                    count++;
                    i--;
                }
                i++;
                j++;
            }
            return ans;
        }
    

    优化

    • 设置四个边界值,动态更新。空间复杂度O(mn)->O(1)

    • 若有边界重合,则打印结束。

    • 原文详细题解

    代码

    /**
      * 1ms  O(mn)
      * 空间复杂度 O(1)
      */
    public static int[] spiralOrder2(int[][] matrix){
            if(matrix.length == 0) return new int[0];
            //定义  l r t b 四个边界
            int l = 0, r = matrix[0].length - 1, t = 0, b = matrix.length - 1, x = 0;
            int[] res=new int[(r+1)*(b+1)];
            while(true){//若有边界重合 打印结束
                for(int i=1;i<=r;i++) res[x++]=matrix[t][i];//left->right
                if(++t>b) break;//判断上下边界是否重合 未重合,则top->bottom
                for(int i=1;i<=b;i++) res[x++]=matrix[i][r];//top->bottom
                if(l>--r) break;//判断右左边界是否重合 未重合,则right->left
                for(int i=r;i>=l;i--) res[x++]=matrix[b][i];//right->left
                if(t>--b) break;//判断下上边界是否重合 未重合,则bottom->top
                for(int i=b;i>=t;i--) res[x++]=matrix[i][l];//bottom->top
                if(++l>r) break;//判断左右边界是否重合 未重合,则left->right
            }
            return res;
    }
    

    参考链接

    krahets:模拟、设定边界、清晰图解

  • 相关阅读:
    代码习惯
    全网最详细的fhq treap (非旋treap)讲解
    按位或「HAOI2015」
    列队「NOIP2017」
    愤怒的小鸟「NOIP2016」
    能量传输「CSP多校联考 2019」
    矿物运输「CSP多校联考 2019」
    普通打击「CSP多校联考 2019」
    普通快乐「CSP多校联考 2019」
    BZOJ4385: [POI2015]Wilcze doły
  • 原文地址:https://www.cnblogs.com/yh-simon/p/13054293.html
Copyright © 2020-2023  润新知