题目描述
给你一个 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
解法一
思路:
遍历存在顺序,记录起始位置和边界位置,一共m*n个数。
代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class leetcode_019 {public static List<Integer> spiralOrder(int[][] matrix) {List<Integer> res = new ArrayList<>();int m=matrix.length,n=matrix[0].length;int allcount=m*n;int i,j;int iStart=0,jStart=0;//边界值int rowBoundary=m,colBoundary=n;while(rowBoundary>=iStart&&colBoundary>=jStart){for(j=jStart,i=iStart;j<colBoundary;j++){res.add(matrix[i][j]);allcount--;}j--;if(allcount==0)break;for(i=iStart+1;i<rowBoundary;i++){res.add(matrix[i][j]);allcount--;}i--;if(allcount==0)break;for(j=j-1; j>=jStart; j--){res.add(matrix[i][j]);allcount--;}j++;if(allcount==0)break;for(i=i-1;i>iStart;i--) {res.add(matrix[i][j]);allcount--;}iStart=iStart+1;jStart=jStart+1;rowBoundary=rowBoundary-1;colBoundary=colBoundary-1;}return res;}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 使用动态结构暂存数据List<int[]> matrixList = new ArrayList<>();while (scanner.hasNextLine()) {//trim()去除字符串两端空白符String line = scanner.nextLine().trim();// 空行表示输入结束if (line.isEmpty()) {break;}// 分割字符串并转换为整数数组String[] values = line.split(",");int[] row = new int[values.length];for (int i = 0; i < values.length; i++) {row[i] = Integer.parseInt(values[i].trim());}matrixList.add(row);}// 转换为二维数组int rows = matrixList.size();int cols = matrixList.get(0).length;int[][] matrix = new int[rows][cols];for (int i = 0; i < rows; i++) {matrix[i] = matrixList.get(i);}List<Integer> res = spiralOrder(matrix);for (Integer integer : res) {System.out.print(integer + " ");}}}
解法二
思路:
来自官方。可以模拟螺旋矩阵的路径。初始位置是矩阵的左上角,初始方向是向右,当路径超出界限或者进入之前访问过的位置时,顺时针旋转,进入下一个方向。判断路径是否进入之前访问过的位置需要使用一个与输入矩阵大小相同的辅助矩阵 visited,其中的每个元素表示该位置是否被访问过。当一个元素被访问时,将 visited 中的对应位置的元素设为已访问。由于矩阵中的每个元素都被访问一次,因此路径的长度即为矩阵中的元素数量,当路径的长度达到矩阵中的元素数量时即为完整路径,将该路径返回。
代码:
class Solution {public List<Integer> spiralOrder(int[][] matrix) {List<Integer> order = new ArrayList<Integer>();if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {return order;}int rows = matrix.length, columns = matrix[0].length;boolean[][] visited = new boolean[rows][columns];int total = rows * columns;int row = 0, column = 0;int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};int directionIndex = 0;for (int i = 0; i < total; i++) {order.add(matrix[row][column]);visited[row][column] = true;int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];if (nextRow < 0 || nextRow >= rows || nextColumn < 0 || nextColumn >= columns || visited[nextRow][nextColumn]) {directionIndex = (directionIndex + 1) % 4;}row += directions[directionIndex][0];column += directions[directionIndex][1];}return order;}
}