zoukankan      html  css  js  c++  java
  • 【LeetCode】面试题29. 顺时针打印矩阵

    题目描述

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

    示例 1:

    输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
    输出:[1,2,3,6,9,8,7,4,5]
    

    示例 2:

    输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
    输出:[1,2,3,4,8,12,11,10,9,5,6,7]
    

    限制:

    • 0 <= matrix.length <= 100
    • 0 <= matrix[i].length <= 100
      注意:本题与主站 54 题相同:54. 螺旋矩阵

    题解

    顺时针方向打印无非就是按着“右下左上”的方向进行遍历并打印,碰到边界就拐弯,然后再缩小边界。

    源码有JavaCC++两种,思路基本差不多。

    class Solution {
        public int[] spiralOrder(int[][] matrix) {
            if(matrix.length == 0) return new int[0];
            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) {
                // left to right.
                for(int i = l; i <= r; i++) res[x++] = matrix[t][i]; 
                if(++t > b) break;
    
                // top to bottom.
                for(int i = t; i <= b; i++) res[x++] = matrix[i][r]; 
                if(l > --r) break;
    
                // right to left.
                for(int i = r; i >= l; i--) res[x++] = matrix[b][i]; 
                if(t > --b) break;
                
                // bottom to top.
                for(int i = b; i >= t; i--) res[x++] = matrix[i][l]; 
                if(++l > r) break;
            }
            return res;
        }
    }
    

    /**
     * Note: The returned array must be malloced, assume caller calls free().
     */
    int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize){
        if (matrix == NULL || matrixSize == 0) {
            *returnSize = 0;
            return NULL;
        }
    
        *returnSize = matrixSize * matrixColSize[0];
        int *res = calloc(*returnSize, sizeof(int));
    
        int i = 0;
        int urow, rcol, drow, lcol, r, c;
        urow = -1;
        lcol = -1;
        drow = matrixSize;
        rcol = matrixColSize[0];
    
        while (i < *returnSize) {
            //right
            r = urow + 1;
            for (c = lcol + 1; i < *returnSize && c < rcol; c++) {
                res[i] = matrix[r][c];
                i++;
            }
            urow++;
    
            //down
            c = rcol - 1;
            for (r = urow + 1; i < *returnSize && r < drow; r++) {
                res[i] = matrix[r][c];
                i++;
            }
            rcol--;
    
            //left
            r = drow - 1;
            for (c = rcol - 1; i < *returnSize && c > lcol; c--) {
                res[i] = matrix[r][c];
                i++;
            }
            drow--;
    
            //up
            c = lcol + 1;
            for (r = drow - 1; i < *returnSize && r > urow; r--) {
                res[i] = matrix[r][c];
                i++;
            }
            lcol++;
        }
    
        return res;
    }
    

    class Solution {
    public:
        vector<int> spiralOrder(vector<vector<int>>& matrix) {
            // 边界情况
            auto height = matrix.size();
            if (!height) return {};
            auto width = matrix[0].size();
            if (!width) return {};
            // 至少有一个元素
            int dx[4]{1, 0, -1, 0}; // 代表 4 个变化方向
            int dy[4]{0, 1, 0, -1}; // 同上
            int d = 0;         // 记录当前方向
            int h = 0, w = 0;  // 记录当前索引
            int cycle = 0;     // 记录当前是第几轮
            vector<int> ans;
            for (int i = 0; i != height * width; ++i) {
                // 到达右边界
                if (!d && w >= width - 1 - cycle) d = ++d % 4;
                // 到达下边界
                if (d == 1 && h >= height - 1 - cycle) d = ++d % 4;
                // 到达左边界
                if (d == 2 && w <= cycle) d = ++d % 4;
                // 到达上边界
                if (d == 3 && h <= cycle + 1) {
                    d = ++d % 4;
                    // 进入下一轮
                    ++cycle;
                }
    
                ans.push_back(matrix[h][w]);
                h += dy[d];
                w += dx[d];
            }
            return ans;
        }
    };
    

    推荐

    极力推荐两个我喜欢的算法公众号的文章:

    1. 面试题29. 顺时针打印矩阵
    2. 顺时针打印矩阵
  • 相关阅读:
    框架基础
    Servlet
    JSP数据交互二
    动态网页开发基础
    数据交互
    期末Java Web大作业----简易的学生管理系统
    南阳71----独木舟上的旅行
    南阳1092----数字分隔(二)
    顺序表、链表、栈和队列
    各类排序模版(计数排序、基数排序、桶排序、冒泡排序、选择排序、插入排序、希尔排序、归并排序、原地归并排序、快速排序、堆排序)
  • 原文地址:https://www.cnblogs.com/melodyjerry/p/13048998.html
Copyright © 2011-2022 走看看