Algorithm

Spiral Matrix – clockwise and counter-clockwise

spiral-matrix
Written by Mushfiq Mammadov

Print matrix elements as spiral order from beginning the center element. It should be as the following picture:

package az.mm.spiralmatrix;

import java.util.Scanner;

/**
 *
 * @author MM <[email protected]>
 */
public class Main {
    private static int row;
    private static int column;
    private int[][] matrix;

    public Main() {
        createMatrix();
    }

    public static void main(String[] args) {
        System.out.println("Please enter matrix lengths (example 4 3):");
        
        Scanner sc = new Scanner(System.in);
        row = sc.nextInt();
        column = sc.nextInt();
        Main m = new Main();
        m.spiralMatrixClockwise();
        m.spiralMatrixCounterClockwise();
    }

    private void spiralMatrixClockwise() {
        System.out.println("\nClockwise elements:");

        int left = (column%2 == 0) ? (column/2 - 1) : (column/2);
        int right = left + 1;
        int top = (row%2 == 0) ? (row/2 - 1) : (row/2);
        int bottom = top + 1;

        OUTER: while (true) {

            for (int i = left; i < right; i++) {
                if(!printElement(top, i)) break OUTER;
            }
            left--;

            for (int i = top; i < bottom; i++) {
                if(!printElement(i, right)) break OUTER;
            }
            top--;

            for (int i = right; i > left; i--) {
                if(!printElement(bottom, i)) break OUTER;
            }
            right++;

            for (int i = bottom; i > top; i--) {
                if(!printElement(i, left)) break OUTER;
            }
            bottom++;
        }
    }
    
    private void spiralMatrixCounterClockwise() {
        System.out.println("\n\nCounter Clockwise elements:");
        
        int right = column/2;
        int left = right - 1;
        int top = (row%2 == 0) ? (row/2 - 1) : (row/2);
        int bottom = top + 1;
        
        OUTER: while (true) {

            for (int i = right; i > left; i--) {
                if(!printElement(top, i)) break OUTER;
            }
            right++;

            for (int i = top; i < bottom; i++) {
                if(!printElement(i, left)) break OUTER;
            }
            top--;

            for (int i = left; i < right; i++) {
                if(!printElement(bottom, i)) break OUTER;
            }
            left--;
           
            for (int i = bottom; i > top; i--) {
                if(!printElement(i, right)) break OUTER;
            }
            bottom++;
        }
    }
    
    private boolean printElement(int i, int j) {
        if (i<0 || i>=row || j<0 || j>=column) return false;
        System.out.print(matrix[i][j] + " ");
       return true;
    }

    private void createMatrix() {
        matrix = new int[row][column];
        int value = 1;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.print((matrix[i][j] = value++) + "\t");
            }
            System.out.println();
        }
    }
}

Output:

Please enter matrix lengths (example 4 3):
4 3
1	2	3	
4	5	6	
7	8	9	
10	11	12	

Clockwise elements:
5 6 9 8 7 4 1 2 3 

Counter Clockwise elements:
5 4 7 8 9 6 3 2 1

 

The following video is short review about how the above code works:

You can also test it via this link.

 

Github link:

https://github.com/mmushfiq/SpiralMatrixSpringMVC

 

But for loop was used many times in the above code. So I optimized and rewrote code again:

package az.mm.spiralmatrix;

import java.util.Scanner;

/**
 * @author MM <[email protected]>
 */
public class Main3 {
    private static int row, col, matrix[][];
    private static boolean isClockwise = true;
    
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.println("Please enter matrix lengths (example 4 3):");
        row = sc.nextInt();
        col = sc.nextInt();
        createMatrix();
        printSpiralElements();
    }
 
    private static void printSpiralElements(){
        System.out.println(isClockwise ? "Clockwise:" : "Counter-Clockwise");
        int i = row%2 == 0 ? row/2-1 : row/2;
        int j = isClockwise ? col%2 == 0 ? col/2-1 : col/2 : col/2;
        int direction=0, steps=1, currentStep=0, change=0; 
 
        for (int a = 0; a < row*col; a++){
            if (i<0 || i>=row || j<0 || j>=col) break; //This condition is important for non-square matrices
            System.out.print(matrix[i][j]+" ");
 
            if (currentStep < steps) 
                currentStep++;
            else {
                currentStep = 1;
                if (change == 1) steps++;
                change = (change+1) % 2;
                direction = (direction+1) % 4;
            }
            
            switch (direction){
                case 0: if(isClockwise) j++; else j--; break;
                case 1: i++; break;
                case 2: if(isClockwise) j--; else j++; break;
                case 3: i--; break;
            }
        }
    }
 
    private static void createMatrix() {
        matrix = new int[row][col];
        int value = 1;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) 
                System.out.print((matrix[i][j] = value++) + "\t");
            System.out.println();
        }
    }
}

Output:

Please enter matrix lengths (example 4 3):
4 6
1	2	3	4	5	6	
7	8	9	10	11	12	
13	14	15	16	17	18	
19	20	21	22	23	24	
Clockwise:
9 10 16 15 14 8 2 3 4 5 11 17 23 22 21 20 19 13 7 1

 

Then it is added two features:

  1. If center element is more than 1 so you can choose it;
  2. All elements of matrix was included to spiral order. 

The last version of code after all updates:

package az.mm.spiralmatrix;

import java.util.Scanner;

/**
 * @author MM <[email protected]>
 */
public class Main4 {
    private static int row, col, matrix[][], maxCenter, centerN;
    private static final boolean isClockwise = true;
    
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println("\nPlease enter matrix lengths (example 4 3):");
            row = sc.nextInt();
            col = sc.nextInt();
            matrix = new int[row][col];
            maxCenter = (row%2==0 && col%2==0) ? 4 : (row%2==0 || col%2==0) ? 2 : 1;
            if (maxCenter != 1){ 
                System.out.println("Please enter center element number: 1 - " + maxCenter);
                centerN = sc.nextInt();
            }
            start();
        }
    }
 
    private static void start(){
        System.out.println(isClockwise ? "Clockwise:" : "Counter-Clockwise");
        int i=row/2, j=col/2;
        if(maxCenter > 1){ 
            if((row%2 == 0 && centerN==1) || (maxCenter>2 && centerN==2)) i=row/2-1; 
            if((col%2 == 0 && centerN==1) || (maxCenter>2 && centerN==3)) j=col/2-1;
        }
        int direction=0, steps=1, currentStep=0, change=0; 
 
        for (int a = 1; a <= row*col; a++){
            if (i<0 || i>=row || j<0 || j>=col) a--;        
            else matrix[i][j] = a;
            
            if (currentStep < steps) 
                currentStep++;
            else {
                currentStep = 1;
                if (change == 1) steps++;
                change = (change+1) % 2;
                direction = (direction+1) % 4;
            }
            
            switch (direction){
                case 0: if(isClockwise) j++; else j--; break;
                case 1: i++; break;
                case 2: if(isClockwise) j--; else j++; break;
                case 3: i--; break;
            }
        }
        printMatrix();
    }
    
    private static void printMatrix(){
        for (int i = 0; i < row; i++){
            for (int j = 0; j < col; j++)
                System.out.print(matrix[i][j] + "\t");
            System.out.println();
        }
    }
}

Output:

Please enter matrix lengths (example 4 3):
6 8
Please enter center element number: 1 - 4
2
Clockwise:
48	42	21	22	23	24	25	26	
47	41	20	7	8	9	10	27	
46	40	19	6	1	2	11	28	
45	39	18	5	4	3	12	29	
44	38	17	16	15	14	13	30	
43	37	36	35	34	33	32	31

 

Github link:

https://github.com/mmushfiq/SpiralMatrixConsole 

 

About the author

Mushfiq Mammadov

2 Comments

  • Hello,
    I tried this code on the java platform in my laptop. the very last output doesn’t match with the code…. I mean to say as illustrated in the example just before this particular code. It should be clockwise as per the example but it prints in the anticlockwise pattern.
    Hope you would look into this. 🙂

    • You are right. The following code line
      private static final boolean isClockwise = false;
      should be
      private static final boolean isClockwise = true;

      I fixed it. Thanks for your response.

Leave a Reply to Mushfiq Mammadov X

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.