【一刷《剑指Offer》】面试题 20:顺时针打印矩阵

简介: 【一刷《剑指Offer》】面试题 20:顺时针打印矩阵

力扣对应题目链接:54. 螺旋矩阵 - 力扣(LeetCode)

牛客对应题目链接:顺时针打印矩阵_牛客题霸_牛客网 (nowcoder.com)


一、《剑指 Offer》内容


二、分析题目

写法二解法:

可以将矩阵看成若干层,首先输出最外层的元素,其次输出次外层的元素,直到输出最内层的元素。

定义矩阵的第 k 层是到最近边界距离为 k 的所有顶点。

对于每层,从左上方开始以顺时针的顺序遍历所有元素。假设当前层的左上角位于 (top, left),右下角位于 (bottom, right),按照如下顺序遍历当前层的元素:

  1. 从左到右遍历上侧元素,依次为 (top, left) 到 (top, right)。
  2. 从上到下遍历右侧元素,依次为 (top+1, right) 到 (bottom, right)。
  3. 如果 left < right 且 top < bottom,则从右到左遍历下侧元素,依次为 (bottom, right−1) 到 (bottom, left+1),以及从下到上遍历左侧元素,依次为 (bottom,left) 到 (top+1,left)。

遍历完当前层的元素之后,将 left 和 top 分别增加 1,将 right 和 bottom 分别减少 1,进入下一层继续遍历,直到遍历完所有元素为止。


三、代码

1、写法一

//力扣
class Solution {
private:
    vector<int> res;
public:
    void printCircle(vector<vector<int>>& matrix, int n, int m, int st)
    {
        int endX=n-1-st, endY=m-1-st;
        //左->右
        for(int j=st; j<=endY; j++)
            res.push_back(matrix[st][j]);
        //上->下
        if(st<endX)
            for(int i=st+1; i<=endX; i++)
                res.push_back(matrix[i][endY]);
        //右->左
        if(st<endX && st<endY)
            for(int j=endY-1; j>=st; j--)
                res.push_back(matrix[endX][j]);
        //下->上
        if(st<endY && st<endX-1)
            for(int i=endX-1; i>=st+1; i--)
                res.push_back(matrix[i][st]);
    }
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        //n行m列
        int n=matrix.size();
        if(n==0) return res;
        int m=matrix[0].size();
        int st=0;
        while(n>st*2 && m>st*2)
        {
            //一圈一圈打印
            printCircle(matrix, n, m, st);
            st++;
        }
        return res;
    }
};
 
//牛客
class Solution {
private:
    vector<int> res;
public:
    void printCircle(vector<vector<int>>& matrix, int n, int m, int st)
    {
        int endX=n-1-st, endY=m-1-st;
        //左->右
        for(int j=st; j<=endY; j++)
            res.push_back(matrix[st][j]);
        //上->下
        if(st<endX)
            for(int i=st+1; i<=endX; i++)
                res.push_back(matrix[i][endY]);
        //右->左
        if(st<endX && st<endY)
            for(int j=endY-1; j>=st; j--)
                res.push_back(matrix[endX][j]);
        //下->上
        if(st<endY && st<endX-1)
            for(int i=endX-1; i>=st+1; i--)
                res.push_back(matrix[i][st]);
    }
    vector<int> printMatrix(vector<vector<int> > matrix) {
        int n=matrix.size();
        if(n==0) return {};
        int m=matrix[0].size();
        int st=0;
        while(n>st*2 && m>st*2)
        {
            //一圈一圈打印
            printCircle(matrix, n, m, st);
            st++;
        }
        return res;
    }
};

2、写法二

//力扣
class Solution {
private:
    vector<int> res;
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        int n=matrix.size();
        if(n==0) return res;
        int m=matrix[0].size();
        int left=0, right=m-1;
        int top=0, bottom=n-1;
        while(left<=right && top<=bottom)
        {
            for(int j=left; j<=right; j++)
                res.push_back(matrix[top][j]);
            for(int i=top+1; i<=bottom; i++)
                res.push_back(matrix[i][right]);
            if(left<right && top<bottom)
            {
                for(int j=right-1; j>=left; j--)
                    res.push_back(matrix[bottom][j]);
                for(int i=bottom-1; i>top; i--)
                    res.push_back(matrix[i][left]);
            }
            left++;
            right--;
            top++;
            bottom--;
        }
        return res;
    }
};


相关文章
|
25天前
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
|
25天前
【一刷《剑指Offer》】面试题 22:栈的压入、弹出系列
【一刷《剑指Offer》】面试题 22:栈的压入、弹出系列
|
25天前
|
算法
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
|
25天前
【一刷《剑指Offer》】面试题 19:二叉树的镜像
【一刷《剑指Offer》】面试题 19:二叉树的镜像
|
25天前
【一刷《剑指Offer》】面试题 18:树的子结构
【一刷《剑指Offer》】面试题 18:树的子结构
|
25天前
【一刷《剑指Offer》】面试题 17:合并两个排序的链表
【一刷《剑指Offer》】面试题 17:合并两个排序的链表
|
25天前
【一刷《剑指Offer》】面试题 16:反转链表
【一刷《剑指Offer》】面试题 16:反转链表
|
25天前
【一刷《剑指Offer》】面试题 15:链表中倒数第 k 个结点
【一刷《剑指Offer》】面试题 15:链表中倒数第 k 个结点
|
25天前
|
C++
【一刷《剑指Offer》】面试题 14:调整数组顺序使奇数位于偶数前面
【一刷《剑指Offer》】面试题 14:调整数组顺序使奇数位于偶数前面
|
25天前
|
机器学习/深度学习
【一刷《剑指Offer》】面试题 13:在 O(1) 时间删除链表结点
【一刷《剑指Offer》】面试题 13:在 O(1) 时间删除链表结点