二维数组螺旋遍历

📝 标题:搞懂二维数组螺旋遍历:从原理到代码实现

在算法面试和日常开发中,二维数组的螺旋遍历是一个高频考点。它不仅考验我们对数组操作的熟悉程度,还能锻炼逻辑思维能力。今天我们就从原理出发,一步步拆解这个经典问题,并用Java、Python、C++三种主流语言实现代码。


🧩 什么是二维数组螺旋遍历?

螺旋遍历,顾名思义,就是按照顺时针(或逆时针)的螺旋顺序,依次访问二维数组中的每个元素。比如对于如下二维数组:

1  2  3  4
5  6  7  8
9 10 11 12
13 14 15 16

它的螺旋遍历结果是:1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10


🚀 核心解题思路

要实现螺旋遍历,关键是要明确每一圈遍历的边界,通过不断缩小边界来完成整个数组的遍历。我们可以用四个变量来定义当前遍历的范围:

  • top:当前遍历的顶部行号
  • bottom:当前遍历的底部行号
  • left:当前遍历的左边界列号
  • right:当前遍历的右边界列号

具体步骤如下:

  1. 从左到右遍历顶部行,遍历完成后top++
  2. 从上到下遍历右边界列,遍历完成后right--
  3. 如果top <= bottom,从右到左遍历底部行,遍历完成后bottom--
  4. 如果left <= right,从下到上遍历左边界列,遍历完成后left++
  5. 重复上述步骤,直到top > bottomleft > right

💻 代码实现

🐍 Python 实现

Python
复制
def spiral_order(matrix):
if not matrix or not matrix[0]:
return []
res = []
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1

while top <= bottom and left <= right:
# 从左到右遍历顶部行
for i in range(left, right + 1):
res.append(matrix[top][i])
top += 1

# 从上到下遍历右边界列
for i in range(top, bottom + 1):
res.append(matrix[i][right])
right -= 1

# 从右到左遍历底部行(需要判断是否还有行)
if top <= bottom:
for i in range(right, left - 1, -1):
res.append(matrix[bottom][i])
bottom -= 1

# 从下到上遍历左边界列(需要判断是否还有列)
if left <= right:
for i in range(bottom, top - 1, -1):
res.append(matrix[i][left])
left += 1
return res

# 测试
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
print(spiral_order(matrix))


☕ Java 实现

Java
复制
import java.util.ArrayList;
import java.util.List;

public class SpiralMatrix {
public static List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<>();
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return res;
}
int top = 0, bottom = matrix.length - 1;
int left = 0, right = matrix[0].length - 1;

while (top <= bottom && left <= right) {
// 从左到右遍历顶部行
for (int i = left; i <= right; i++) {
res.add(matrix[top][i]);
}
top++;

// 从上到下遍历右边界列
for (int i = top; i <= bottom; i++) {
res.add(matrix[i][right]);
}
right--;

// 从右到左遍历底部行
if (top <= bottom) {
for (int i = right; i >= left; i--) {
res.add(matrix[bottom][i]);
}
bottom--;
}

// 从下到上遍历左边界列
if (left <= right) {
for (int i = bottom; i >= top; i--) {
res.add(matrix[i][left]);
}
left++;
}
}
return res;
}

public static void main(String[] args) {
int[][] matrix = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
System.out.println(spiralOrder(matrix));
}
}


➕ C++ 实现

Cpp
复制
#include <iostream>
#include <vector>
using namespace std;

vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> res;
if (matrix.empty() || matrix[0].empty()) {
return res;
}
int top = 0, bottom = matrix.size() - 1;
int left = 0, right = matrix[0].size() - 1;

while (top <= bottom && left <= right) {
// 从左到右遍历顶部行
for (int i = left; i <= right; ++i) {
res.push_back(matrix[top][i]);
}
top++;

// 从上到下遍历右边界列
for (int i = top; i <= bottom; ++i) {
res.push_back(matrix[i][right]);
}
right--;

// 从右到左遍历底部行
if (top <= bottom) {
for (int i = right; i >= left; --i) {
res.push_back(matrix[bottom][i]);
}
bottom--;
}

// 从下到上遍历左边界列
if (left <= right) {
for (int i = bottom; i >= top; --i) {
res.push_back(matrix[i][left]);
}
left++;
}
}
return res;
}

int main() {
vector<vector<int>> matrix = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
vector<int> result = spiralOrder(matrix);
for (int num : result) {
cout << num << " ";
}
cout << endl;
return 0;
}


🎯 边界情况处理

在实现过程中,我们需要特别注意以下边界情况:

  1. 空数组或空行:直接返回空列表
  2. 只有一行的数组:直接从左到右遍历
  3. 只有一列的数组:直接从上到下遍历
  4. 遍历过程中出现top > bottomleft > right的情况,要及时终止循环

📌 总结

二维数组的螺旋遍历问题,核心在于通过边界变量来控制遍历范围,逐步缩小遍历区域。只要理清了遍历的顺序和边界条件,用任何语言都能轻松实现。希望这篇文章能帮助你彻底搞懂这个经典算法问题!

会员自媒体 数据结构与算法 二维数组螺旋遍历 https://yuelu1.cn/26103.html

相关文章

猜你喜欢