将一个二维矩阵,螺旋遍历展开为一维列表

python 复制代码
matrix = [[1, 2, 3, 4],
          [5, 6, 7, 8],
          [9, 10, 11, 12]]

# 获取二维列表的行数并存放到变量 rows 中
# 获取二维列表的列数并存放到变量 cols 中
rows = len(matrix)
cols = len(matrix[0])

left = 0
right = cols - 1
top = 0
bottom = rows - 1

result = []

while left <= right and top <= bottom:
    # 从左往右遍历
    for col in range(left, right + 1):
        result.append(matrix[top][col])
    # 从上往下遍历
    for row in range(top + 1, bottom + 1):
        result.append(matrix[row][right])
    if left < right and top < bottom:
        # 从右往左遍历
        for col in range(right - 1, left, -1):
            result.append(matrix[bottom][col])
        # 从下往上遍历
        for row in range(bottom, top, -1):
            result.append(matrix[row][left])
    left = left + 1
    right = right - 1
    top = top + 1
    bottom = bottom - 1

print(result)

这个代码的目的是将一个二维矩阵按照螺旋顺序(也叫做"螺旋遍历")展开为一维列表。我们来详细分析这个代码:

1. **初始化矩阵和变量**

```python

matrix = [[1, 2, 3, 4],

[5, 6, 7, 8],

[9, 10, 11, 12]]

```

这是一个 3x4 的二维矩阵,矩阵有 3 行和 4 列。接下来,我们会从这个矩阵中按照螺旋顺序读取所有元素。

```python

rows = len(matrix)

cols = len(matrix[0])

```

`rows` 是矩阵的行数,`cols` 是矩阵的列数。这里的 `rows` 为 3,`cols` 为 4。

接下来定义了四个边界:

  • `left`: 记录当前遍历区域的最左列

  • `right`: 记录当前遍历区域的最右列

  • `top`: 记录当前遍历区域的最上行

  • `bottom`: 记录当前遍历区域的最下行

初始化时,`left = 0`,`right = cols - 1`(即 3),`top = 0`,`bottom = rows - 1`(即 2)。

```python

result = []

```

`result` 用于存放遍历过程中按照螺旋顺序读取的矩阵元素。

2. **开始螺旋遍历**

```python

while left <= right and top <= bottom:

```

`while` 循环的条件确保了只要遍历区域有效(即仍然有元素未被遍历),就会继续执行。直到遍历到所有元素为止。

在每一轮遍历中,按顺时针的顺序从矩阵的四个边界依次读取元素:

2.1 **从左往右遍历**

```python

for col in range(left, right + 1):

result.append(matrix[top][col])

```

这段代码表示从 `top` 行的 `left` 列到 `right` 列遍历,将每个元素加入 `result`。即遍历当前最上面的一行。

2.2 **从上往下遍历**

```python

for row in range(top + 1, bottom + 1):

result.append(matrix[row][right])

```

这段代码表示从 `right` 列的 `top + 1` 行到 `bottom` 行遍历,将每个元素加入 `result`。即遍历当前最右面的一列(跳过已经遍历过的最上面一行)。

2.3 **从右往左遍历(仅当有多余行和列时)**

```python

if left < right and top < bottom:

for col in range(right - 1, left, -1):

result.append(matrix[bottom][col])

```

这段代码表示从 `bottom` 行的 `right - 1` 列到 `left` 列反向遍历,将每个元素加入 `result`。即遍历当前最下面的一行(跳过已经遍历过的最右边一列)。注意,`if left < right and top < bottom:` 这个条件确保只有当当前行数和列数足够的时候,才进行这一步。如果已经没有剩余的行或列,就不再执行这一步。

2.4 **从下往上遍历(仅当有多余行和列时)**

```python

for row in range(bottom, top, -1):

result.append(matrix[row][left])

```

这段代码表示从 `bottom` 行的 `left` 列到 `top + 1` 行反向遍历,将每个元素加入 `result`。即遍历当前最左边的一列(跳过已经遍历过的最下面一行)。同样,`if left < right and top < bottom:` 这个条件确保只有在剩余部分足够时才进行这一步。

3. **更新边界**

```python

left = left + 1

right = right - 1

top = top + 1

bottom = bottom - 1

```

每完成一轮遍历后,更新矩阵的四个边界:

  • `left` 增加 1,意味着左边界右移;

  • `right` 减少 1,意味着右边界左移;

  • `top` 增加 1,意味着上边界下移;

  • `bottom` 减少 1,意味着下边界上移。

4. **输出结果**

```python

print(result)

```

最终输出螺旋顺序遍历的结果。

5. **整体流程示例**

假设矩阵如下:

```

[[ 1, 2, 3, 4],

[ 5, 6, 7, 8],

[ 9, 10, 11, 12]]

```

遍历过程如下:

  • 第一轮:从左到右遍历第一行 `[1, 2, 3, 4]`,从上到下遍历最后一列 `[8, 12]`,从右到左遍历最后一行 `[11, 10, 9]`,从下到上遍历第一列 `[5]`。

  • 第二轮:从左到右遍历第二行 `[6, 7]`,完成所有元素遍历。

最终 `result` 中的元素是:

```

[1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]

```

6. **总结**

这个算法的核心思路是通过设置四个边界,不断缩小遍历的区域,每次按顺时针方向遍历矩阵的四个边界,直到矩阵所有元素被遍历完。

相关推荐
不去幼儿园40 分钟前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Mr_Xuhhh42 分钟前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
盼海2 小时前
排序算法(五)--归并排序
数据结构·算法·排序算法
网易独家音乐人Mike Zhou5 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
Guofu_Liao6 小时前
大语言模型---LoRA简介;LoRA的优势;LoRA训练步骤;总结
人工智能·语言模型·自然语言处理·矩阵·llama
Swift社区9 小时前
LeetCode - #139 单词拆分
算法·leetcode·职场和发展
Kent_J_Truman9 小时前
greater<>() 、less<>()及运算符 < 重载在排序和堆中的使用
算法
IT 青年10 小时前
数据结构 (1)基本概念和术语
数据结构·算法
Dong雨10 小时前
力扣hot100-->栈/单调栈
算法·leetcode·职场和发展
SoraLuna10 小时前
「Mac玩转仓颉内测版24」基础篇4 - 浮点类型详解
开发语言·算法·macos·cangjie