C++刷题笔记(5)——leetcode54、59

螺旋矩阵的高效实现与生成
这篇博客探讨了如何高效地解决螺旋矩阵问题。针对题目54.螺旋矩阵,作者分享了两种解题方法,一种是逐步边界调整的详细过程,另一种是简化后的迭代解法,通过维护上下左右边界和未遍历的数目来简化判断条件。同时,还提供了题目59.螺旋矩阵Ⅱ的解决方案,展示了如何生成一个填充了1到n^2的螺旋矩阵。

题目1:54.螺旋矩阵

在这里插入图片描述
解题思路:

螺旋结构重要的是模拟顺时针画矩阵的过程:
填充上行从左到右、填充右列从上到下、填充下行从右到左、填充左列从下到上,由外向内一圈一圈的画
在这里插入图片描述
首先就是定义上下左右四个边界,然后从第一行开始遍历数组,当遍历完成,上边界下移;

注意需要判断上下边界是否出现重叠,如果出现重叠表示螺旋矩阵遍历结束,跳出循环,返回答案;

若上下边界不重叠,表示遍历还没有完成,接着向下向左向上移动,不断循环以上步骤,直到某两条边界交错,跳出循环,返回答案

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {   //Vector容器嵌套容器
        vector <int> result;
        if (matrix.empty()) return result;           //若数组为空,直接返回答案
        int up = 0;                                  //定义上边界
        int down = matrix.size() - 1;                //定义下边界
        int left = 0;                                //定义左边界
        int right = matrix[0].size() - 1;            //定义右边界
        while (true)
        {
            for (int i = left; i <= right; ++i) {
                result.push_back(matrix[up][i]);     //从第一行开始遍历数组、向右移动
            }
            up++;                                    //重新设定上边界
            if (up > down)                           //若上边界大于下边界,则遍历遍历完成,下同
                break; 
            for (int i = up; i <= down; ++i) {
                result.push_back(matrix[i][right]);  //向下移动
            }
            right--;                                 //重新设定右边界
            if (right < left) 
                break; 
            for (int i = right; i >= left; --i) {
                result.push_back(matrix[down][i]);   //向左移动
            }
            down--;                                  //重新设定下边界
            if (down < up) 
                break; 
            for (int i = down; i >= up; --i) {
                result.push_back(matrix[i][left]);   //向上移动
            }
            left++;                                  //重新设定左边界
            if (left > right) 
                break; 
        }
        return result;
    }
};

但是上面这种写法很麻烦,在做题过程中要不断的进行修补判断语句。

评论区大佬超级超级无敌简洁的解法

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> ans;
        int u = 0, d = matrix.size() - 1, l = 0, r = matrix[0].size() - 1;    //上下左右边界
        int num = matrix.size() * matrix[0].size();                           //矩阵中有多少数
        while (num) {              //遍历矩阵,每次遍历完后更新边界即可,同时记录未遍历的数目,为零时跳出
            for (int i = l; num && i <= r; i++, num--) ans.push_back(matrix[u][i]); u++;
            for (int i = u; num && i <= d; i++, num--) ans.push_back(matrix[i][r]); r--;
            for (int i = r; num && i >= l; i--, num--) ans.push_back(matrix[d][i]); d--;
            for (int i = d; num && i >= u; i--, num--) ans.push_back(matrix[i][l]); l++;
        }
        //while (true)
        //{
        //    for (int i = l; i <= r; ++i) ans.push_back(matrix[u][i]); //向右移动直到最右
        //    if (++u > d) break; //重新设定上边界,若上边界大于下边界,则遍历遍历完成,下同
        //    for (int i = u; i <= d; ++i) ans.push_back(matrix[i][r]); //向下
        //    if (--r < l) break; //重新设定有边界
        //    for (int i = r; i >= l; --i) ans.push_back(matrix[d][i]); //向左
        //    if (--d < u) break; //重新设定下边界
        //    for (int i = d; i >= u; --i) ans.push_back(matrix[i][l]); //向上
        //    if (++l > r) break; //重新设定左边界
        //}
        return ans;
    }
};

题目2:59.螺旋矩阵Ⅱ

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) { 
        vector<vector<int>> result(n, vector<int>(n));       //使用vector定义一个二维数组
        int up = 0, down = n - 1, left = 0, right = n - 1;   //定义上下左右边界
        int k = 1;                  //通过累加将1~n^2填入二维数组
        while (k <= n * n) {
            for (int i = left; i <= right; i++, k++) result[up][i] = k; up++;
            for (int i = up; i <= down; i++, k++) result[i][right] = k; right--; 
            for (int i = right; i >= left; i--, k++) result[down][i] = k; down--;
            for (int i = down; i >= up; i--, k++) result[i][left] = k; left++;
        }
        return result;
    }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值