螺旋矩阵 IV
难度:
标签:
题目描述
给你两个整数:m
和 n
,表示矩阵的维数。
另给你一个整数链表的头节点 head
。
请你生成一个大小为 m x n
的螺旋矩阵,矩阵包含链表中的所有整数。链表中的整数从矩阵 左上角 开始、顺时针 按 螺旋 顺序填充。如果还存在剩余的空格,则用 -1
填充。
返回生成的矩阵。
示例 1:

输入:m = 3, n = 5, head = [3,0,2,6,8,1,7,9,4,2,5,5,0] 输出:[[3,0,2,6,8],[5,0,-1,-1,1],[5,2,4,9,7]] 解释:上图展示了链表中的整数在矩阵中是如何排布的。 注意,矩阵中剩下的空格用 -1 填充。
示例 2:

输入:m = 1, n = 4, head = [0,1,2] 输出:[[0,1,2,-1]] 解释:上图展示了链表中的整数在矩阵中是如何从左到右排布的。 注意,矩阵中剩下的空格用 -1 填充。
提示:
1 <= m, n <= 105
1 <= m * n <= 105
- 链表中节点数目在范围
[1, m * n]
内 0 <= Node.val <= 1000
代码结果
运行时间: 260 ms, 内存: 53.9 MB
/*
* 题目思路:
* 1. 初始化一个 m x n 大小的矩阵,初始值为 -1。
* 2. 使用 IntStream 来生成螺旋顺序的索引。
* 3. 使用方向数组和 lambda 表达式来控制方向变化。
* 4. 遍历链表,将节点的值填入矩阵中。
* 5. 当遇到边界或已经填充过的位置时,改变方向。
*/
import java.util.stream.IntStream;
import java.util.Arrays;
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class SpiralMatrixStream {
public int[][] spiralMatrix(int m, int n, ListNode head) {
int[][] matrix = new int[m][n];
IntStream.range(0, m).forEach(i -> Arrays.fill(matrix[i], -1));
int[] dx = {0, 1, 0, -1};
int[] dy = {1, 0, -1, 0};
int[] pos = {0, 0};
int[] dir = {0};
ListNode curr = head;
IntStream.range(0, m * n).forEach(i -> {
if (curr != null) {
matrix[pos[0]][pos[1]] = curr.val;
curr = curr.next;
}
int nx = pos[0] + dx[dir[0]];
int ny = pos[1] + dy[dir[0]];
if (nx < 0 || nx >= m || ny < 0 || ny >= n || matrix[nx][ny] != -1) {
dir[0] = (dir[0] + 1) % 4;
nx = pos[0] + dx[dir[0]];
ny = pos[1] + dy[dir[0]];
}
pos[0] = nx;
pos[1] = ny;
});
return matrix;
}
}
解释
方法:
题解的思路是首先创建一个m x n的矩阵,初始化所有元素为-1。然后定义四个变量t, b, l, r分别表示矩阵的上边界、下边界、左边界和右边界。通过一个while循环,按螺旋顺序逐个填充矩阵。每填充完一圈(或矩阵的一部分),就相应地更新边界变量(例如填充完顶部一行后,t自增)。循环每次检查链表是否还有节点,如果没有,即提前返回矩阵。否则,继续填充直到链表耗尽。
时间复杂度:
O(max(L, m * n))
空间复杂度:
O(m * n)
代码细节讲解
🦆
题解中提到的边界变量(t, b, l, r)在每一步结束后都进行更新,这种更新机制是否能确保在任何情况下不会发生数组越界的错误?
▷🦆
对于循环中的向内移动边界的操作,如何确保在所有的循环完成后,所有应该被填充的格子都被正确填充了?
▷🦆
在链表元素已经全部使用完毕但矩阵尚未完全填满的情况下,题解如何处理未被填充的部分,以保证函数能够正确返回完整的矩阵?
▷