Spiral Order of a Matrix
Problem
Read a matrix. Print all its elements in spiral order: go right along the top row, down the right column, left along the bottom row, up the left column, and then continue inside.
Constraints
- 1 <= r, c <= 100
Examples
Input
3 3 1 2 3 4 5 6 7 8 9
Output
1 2 3 6 9 8 7 4 5
Solutions
We keep four borders around the unvisited part. After walking one side, we move that border inward. The two checks in steps 4 and 5 protect single rows and single columns from being visited twice.
/*
* Problem : Process a matrix.
* Input : r and c, then r rows of c integers.
* Output : Elements in spiral order.
* Approach: Shrink four borders.
* Time : O(r * c)
* Space : O(r * c)
* Java : 8 or newer.
*/
import java.util.Scanner;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static int[] solve(int[][] m) {
int rows = m.length;
int cols = m[0].length;
int[] result = new int[rows * cols];
int index = 0;
// Step 1: The four borders of the part that is not visited yet.
int top = 0;
int bottom = rows - 1;
int left = 0;
int right = cols - 1;
while (top <= bottom && left <= right) {
// Step 2: Go right along the top row, then move the top border down.
for (int j = left; j <= right; j++) {
result[index++] = m[top][j];
}
top++;
// Step 3: Go down along the right column, then move the right border left.
for (int i = top; i <= bottom; i++) {
result[index++] = m[i][right];
}
right--;
// Step 4: Go left along the bottom row (only if a row is left), then move the bottom border up.
if (top <= bottom) {
for (int j = right; j >= left; j--) {
result[index++] = m[bottom][j];
}
bottom--;
}
// Step 5: Go up along the left column (only if a column is left), then move the left border right.
if (left <= right) {
for (int i = bottom; i >= top; i--) {
result[index++] = m[i][left];
}
left++;
}
}
return result;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int rows = scanner.nextInt();
int cols = scanner.nextInt();
int[][] m = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m[i][j] = scanner.nextInt();
}
}
System.out.println(Arrays.stream(solve(m)).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}
Hints (1)
- Why must we check top <= bottom before the third side?