leecode——螺旋矩阵


前言

提示:前两天leecode上面的题都是和hash映射有关,数据结构倒是讲了相关内容,但是孩子当时没有代码实践。。。
总的来说,hash就是一种基于地址直接查找的算法,突破了传统的查找算法,比如,顺序查找,二分查找,B树查找之类的乱七八糟的查找的时间极限。学习了一下代码,倒是没有自己打。


提示:以下是本篇文章正文内容,本次代码思维量较少,还是考察代码功底,注意数组不要越界!

一、题目是什么?

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 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]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、解答

1.我的解答

大致思路是这样的,由于每次读一圈,规律都是相似的,所有考虑递归。本质上就是坐标(i,j)在边界上的循环。

值得注意的是,当写递归主函数的时候,有一些特殊情况要判断,比如只有一行,只有一列,只有两行,只有两列等等,避免重复。

本次代码用时,大概1:30分钟,中间debug主要是两个问题:
1、递归函数传入参数的意义没有特别清楚,其实之前我还尝试过首坐标加行数之类的,但是写着写着自己就搞混了,导致了一些bug。

2、数组越界问题,我记得C语言里面,对于数组越界是没有专门的防护机制的,但是这个C++好像有哦(good!)出现了runtime error 的问题,就是数组角标出现了-1之类的。

代码如下:

class Solution {


public:
    vector<int> result;
    void youCanTry(vector<vector<int>>& matrix,int a,int b,int c,int d){
    //a,b,行首(尾)坐标,c,d,列首(尾)坐标
     if(b<a||d<c) return;//数组坐标越界检查,也是终止条件
     if(b==a&&d==c) {//只有一行一列
     result.push_back(matrix[a][c]);
     return;
     }

     for(int i=c;i<=d;i++){
         result.push_back(matrix[a][i]);
        // cout<<matrix[a][i]<<" ";
     }
     
     if(b==a) return;//只有一行
     
     for(int i=a+1;i<=b;i++){
        // cout<<" wrong";
         result.push_back(matrix[i][d]);
         //cout<<matrix[m-1][i]<<" ";
        //向下
     }
     if(d==c) return;//只有一列
     for(int i=d-1;i>=c;i--){
         result.push_back(matrix[b][i]);
     }
     //<-
     if(a==b-1) return;//只有两行
     for(int i=b-1;i>a;i--){
         result.push_back(matrix[i][c]);
     }
     youCanTry(matrix,a+1,b-1,c+1,d-1);
     }
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
    int m=matrix.size();//行
    int n=matrix[0].size();//列
    youCanTry(matrix,0,m-1,0,n-1);
    return result;
    }
};

性能:
执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗:6.8 MB, 在所有 C++ 提交中击败了42.19%的用户
毕竟用了递归嘛,内存肯定是比纯循环要大的。

2.官方

leetcode官方解答<-点击这里
官方解答很详细了,我总结一些就OK了,官解有两个,一个和我想的差不多,就是循环遍历矩阵,不过官方更厉害一点,他直接就是一个循环,而且代码写的也很漂亮!
另一个是有点意思的,模拟:
他规定了四个方向向量(注意,这个顺序也是有讲究的,符合这个螺旋方向的优先级)
还有一个visited数组,标志是否当前节点被访问过。
值得细细琢磨。

class Solution {
private:
    static constexpr int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (matrix.size() == 0 || matrix[0].size() == 0) {
            return {};
        }
        
        int rows = matrix.size(), columns = matrix[0].size();
        vector<vector<bool>> visited(rows, vector<bool>(columns));
        int total = rows * columns;
        vector<int> order(total);

        int row = 0, column = 0;
        int directionIndex = 0;
        for (int i = 0; i < total; i++) {
            order[i] = matrix[row][column];
            visited[row][column] = true;
            int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
            if (nextRow < 0 || nextRow >= rows || nextColumn < 0 || nextColumn >= columns || visited[nextRow][nextColumn]) {//判断条件:越界,被访问过。
                directionIndex = (directionIndex + 1) % 4;
            }
            //下一个方向向量一定就是了,如果不放心,可以把if改成while。
            //我试了一下,改成while超出了时间限制,还是if把,因为它之前设的方向向量的顺序,就默认了下一个就是对的。
            row += directions[directionIndex][0];
            column += directions[directionIndex][1];
        }
        return order;
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/spiral-matrix/solution/luo-xuan-ju-zhen-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

总结

好好学习,天天向上!!!多尝试,多实践!!! CSAPP我来了!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值