package com.freetymekiyan.algorithms.level.medium; import java.util.ArrayList; import java.util.List; /** * Given a matrix of m x n elements (m rows, n columns), return all elements of * the matrix in spiral order. * <p> * For example, * Given the following matrix: * <p> * [ * [ 1, 2, 3 ], * [ 4, 5, 6 ], * [ 7, 8, 9 ] * ] * You should return [1,2,3,6,9,8,7,4,5]. * <p> * Tags: Array */ class SpiralMatrix { public static void main(String[] args) { } /** * Remember which level it is right now * Do level by level till reach center */ public List<Integer> spiralOrder(int[][] matrix) { List<Integer> res = new ArrayList<Integer>(); if (matrix == null || matrix.length == 0) { return res; } int m = matrix.length; int n = matrix[0].length; int lv = 0; while (2 * lv < m && 2 * lv < n) { // note 2 * level for (int i = lv; i < n - lv; i++) { res.add(matrix[lv][i]); // right } for (int i = lv + 1; i < m - lv; i++) { res.add(matrix[i][n - lv - 1]); // down } if (2 * lv == m - 1 || 2 * lv == n - 1) { break; // reach last row/col } for (int i = n - lv - 2; i >= lv; i--) { res.add(matrix[m - lv - 1][i]); } for (int i = m - lv - 2; i >= lv + 1; i--) { res.add(matrix[i][lv]); } lv++; } return res; } /** * Use rMin, rMax, cMin, cMax, to store the boundries * Use i, j to track the position * Move i, j around to add elements * Break whenever out of bounds to avoid duplicate traversal */ public List<Integer> spiralOrderB(int[][] matrix) { List<Integer> res = new ArrayList<Integer>(); if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { return res; } int iMin = 0; int iMax = matrix.length - 1; int jMin = 0; int jMax = matrix[0].length - 1; int i = 0; int j = 0; // update boundry as soon as we traverse through it while (iMin <= iMax && jMin <= jMax) { for (j = jMin; j <= jMax; j++) { res.add(matrix[iMin][j]); } iMin++; if (iMin > iMax) { break; // break as soon as possible } for (i = iMin; i <= iMax; i++) { res.add(matrix[i][jMax]); } jMax--; if (jMax < jMin) { break; } for (j = jMax; j >= jMin; j--) { res.add(matrix[iMax][j]); } iMax--; if (iMax < iMin) { break; } for (i = iMax; i >= iMin; i--) { res.add(matrix[i][jMin]); } jMin++; } return res; } }