前言
提示:前两天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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。