螺旋遍历二维数组
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 40 ms, 内存: 15.3 MB
/*
* 思路:
* 1. 使用传统的方式构建一个螺旋遍历的列表。
* 2. 将这个列表转化为Java Stream进行处理。
*/
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SpiralOrderStream {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
if (matrix == null || matrix.length == 0) return result;
int top = 0, bottom = matrix.length - 1;
int left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
IntStream.rangeClosed(left, right).forEach(i -> result.add(matrix[top][i]));
top++;
IntStream.rangeClosed(top, bottom).forEach(i -> result.add(matrix[i][right]));
right--;
if (top <= bottom) IntStream.rangeClosed(left, right).map(i -> right - i + left).forEach(i -> result.add(matrix[bottom][i]));
bottom--;
if (left <= right) IntStream.rangeClosed(top, bottom).map(i -> bottom - i + top).forEach(i -> result.add(matrix[i][left]));
left++;
}
return result.stream().collect(Collectors.toList());
}
}
解释
方法:
该题解的主要思路是使用四个指针来标识二维数组的边界:左边界l,右边界r,上边界t,下边界b。初始化时,左边界和上边界设为0,右边界和下边界分别设为列数减一和行数减一。按照题目要求的螺旋顺序,从左到右遍历上边界行,然后下移上边界;从上到下遍历右边界列,然后左移右边界;从右到左遍历下边界行,然后上移下边界;从下到上遍历左边界列,然后右移左边界。每次遍历结束后,检查边界条件以决定是否继续遍历。如果某个方向的新边界越界,则结束螺旋遍历。
时间复杂度:
O(m*n)
空间复杂度:
O(1)
代码细节讲解
🦆
在遍历过程中,如何确保不会重复访问已经遍历过的元素?
▷🦆
如果输入的二维数组是不规则的,例如某些行的列数不同,这种螺旋遍历算法是否仍然适用?
▷🦆
在代码中,边界的检查(例如 `if t > b`)是在每一步遍历后进行的,这种方式是否最优或存在更高效的处理边界的方法?
▷🦆
当二维数组为空或非常小(例如1x1,1x2)时,此算法的行为是怎样的?是否有必要对这些特殊情况进行额外处理?
▷