螺旋矩阵
难度:
标签:
题目描述
给你一个 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
代码结果
运行时间: 36 ms, 内存: 14.8 MB
/*
* 思路:
* 1. 利用Stream流的特性实现螺旋遍历。
* 2. 通过Stream.of()创建流,按顺序访问矩阵的四个边界元素。
* 3. 利用flatMap和collect方法,将遍历结果收集到列表中。
*/
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class SpiralOrderStream {
public List<Integer> spiralOrder(int[][] matrix) {
if (matrix == null || matrix.length == 0) return new ArrayList<>();
List<Integer> result = new ArrayList<>();
int m = matrix.length, n = matrix[0].length;
int left = 0, right = n - 1, top = 0, bottom = m - 1;
while (left <= right && top <= bottom) {
Stream.of(
IntStream.rangeClosed(left, right).map(i -> matrix[top][i]).boxed().collect(Collectors.toList()),
IntStream.rangeClosed(top + 1, bottom).map(i -> matrix[i][right]).boxed().collect(Collectors.toList()),
IntStream.rangeClosed(left, right).map(i -> matrix[bottom][right - i + left]).boxed().collect(Collectors.toList()),
IntStream.rangeClosed(top + 1, bottom).map(i -> matrix[bottom - i + top + 1][left]).boxed().collect(Collectors.toList())
).flatMap(List::stream).forEach(result::add);
top++; right--; bottom--; left++;
}
return result;
}
}
解释
方法:
这个题解采用了螺旋遍历矩阵的方法。初始化矩阵的上下左右四个边界,然后按照右、下、左、上的顺序依次遍历并收缩边界,直到遍历完整个矩阵。具体做法是:先从左到右遍历上边界,然后上边界下移;再从上到下遍历右边界,然后右边界左移;接着从右到左遍历下边界,然后下边界上移;最后从下到上遍历左边界,然后左边界右移。如此循环直至越过边界,遍历结束。
时间复杂度:
O(m*n)
空间复杂度:
O(m*n)
代码细节讲解
🦆
在螺旋矩阵代码中,当某个方向的遍历完成后,边界如何确保不会影响到下一次遍历?
▷🦆
如何处理矩阵的特殊情况,比如单行或单列的情况,在螺旋遍历时边界条件会有何不同?
▷🦆
代码中每次遍历完一个方向后都进行了边界的调整,这样的处理方式是否可能导致重复访问某些元素?
▷🦆
在提供的题解中,存在多个循环结构,这些循环的停止条件是如何设计的,以确保不会超出矩阵的边界?
▷