【力扣刷题】54螺旋矩阵Ⅰ
题目描述
给你一个 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]
提示:
m == matrix.length
n == matrix[i]. length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
题解:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int up = 0, down = matrix.size()-1, left = 0, right = matrix[0].size()-1;
vector<int> res;//up指向第0行,down指向第n-1行
while(up <= down && left <= right){
for(int j = left; j <= right; j++){
res.push_back(matrix[up][j]);//打印第up行
}
if(++up > down) break;//打印完第up行后判断是否还有剩余行,不能是up++
for(int i = up; i <= down; i++){
res.push_back(matrix[i][right]);//打印第right列
}
if(--right < left) break;//right左移一位
for(int j = right; j >= left; j--){
res.push_back(matrix[down][j]);
}
if(--down < up) break;//每打印完一行或是一列后的移动和判断是关键
for(int i = down; i >= up; i--){
res.push_back(matrix[i][left]);
}
if(++left > right) break;
}
return res;
}
};
思路就是按照题目要求去模拟,按up行->right列->down行->left列这个顺序打印,每打印完一行后或是一列后的移动(自增或自减)和判断是关键!
c++代码细节知识点:
- c++中二维数组vector<vector>的size等于元素总个数吗?
在C++中,二维数组std::vector<std::vector<T>>
的size并不直接等于元素总个数。这里的size是指每一维度上的元素数量。(即行数)
当你谈论二维数组(或者说矩阵)的size时,通常指的是它的行数和列数,即二维数组的大小是包含两部分信息的:matrix.size()
(对应于行数)和内部每个向量(即每一行)的matrix[0].size()
(对应于列数)。
要获得整个二维数组元素的总个数,你需要遍历每一行并累加各列元素数量:
std::vector<std::vector<int>> matrix;
// ... 初始化或填充matrix ...
size_t total_elements = 0;
for (const auto& row : matrix) {
total_elements += row.size();
}
这段代码将计算二维vector中所有元素的总个数。如果所有行的长度相等,你也可以直接用第一行的size乘以外部size来快速得到总元素数,假设所有行都有相同的列数:
size_t total_elements = matrix.size() * matrix[0].size();
但是在实际应用中,尤其是当二维数组的列数不固定时,务必检查每一行的大小是否一致,以确保上述简化的计算方式是有效的。
2.size_t total_elements和const auto& row是什么类型?
在C++中:
-
size_t total_elements
是一个无符号整数类型,通常用来表示容器(比如数组、vector等)的大小,它可以容纳任意非负整数值,而且大小足够存储系统所能支持的最大数组索引。在C++标准库中,size_t
被定义在<cstddef>
头文件中,它的具体大小取决于编译器和操作系统,但一般来说,它能够存储当前平台上指针能够指向的任何对象的大小。 -
const auto& row
是一个引用类型,这里的auto
关键字用于类型推导,编译器会根据上下文推断出row
的类型。在遍历std::vector<std::vector<int>> matrix
这样的二维向量时,row
将会被推导为const std::vector<int>&
类型,即它是matrix
中每一项(即每一行)的常量引用。这意味着row
是对std::vector<int>
的一个引用,且由于前面有const
关键字,所以在遍历时不能通过row
修改对应的行数据。
更简洁的代码
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector <int> ans;
if(matrix.empty()) return ans; //若数组为空,直接返回答案
int u = 0; //赋值上下左右边界
int d = matrix.size() - 1;
int l = 0;
int r = matrix[0].size() - 1;
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;
}
};
作者:YouLookDeliciousC
链接:https://leetcode.cn/problems/spiral-matrix/solutions/7155/cxiang-xi-ti-jie-by-youlookdeliciousc-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这里的方法不需要记录已经走过的路径,所以执行用时和内存消耗都相对较小
首先设定上下左右边界
其次向右移动到最右,此时第一行因为已经使用过了,可以将其从图中删去,体现在代码中就是重新定义上边界
判断若重新定义后,上下边界交错,表明螺旋矩阵遍历结束,跳出循环,返回答案
若上下边界不交错,则遍历还未结束,接着向下向左向上移动,操作过程与第一,二步同理
不断循环以上步骤,直到某两条边界交错,跳出循环,返回答案