59

How do I print a 5×5 two-dimensional array in spiral order?

Is there any formula so that I can print an array of any size in spiral order?

codaddict
  • 445,704
  • 82
  • 492
  • 529
Rahul Vyas
  • 28,260
  • 49
  • 182
  • 256

37 Answers37

81

The idea is to treat the matrix as a series of layers, top-right layers and bottom-left layers. To print the matrix spirally we can peel layers from these matrix, print the peeled part and recursively call the print on the left over part. The recursion terminates when we don't have any more layers to print.

Input matrix:

1 2 3 4 
5 6 7 8
9 0 1 2   
3 4 5 6 
7 8 9 1

After peeling top-right layer:

 1 2 3 4 
       8
5 6 7  2
9 0 1  6   
3 4 5  1 
7 8 9

After peeling bottom-left layer from sub-matrix:

   6 7
5  0 1   
9  4 5
3 
7 8 9 

After peeling top-right layer from sub-matrix:

    6 7
      1   
   0  5
   4

After peeling bottom-left layer from sub-matrix:

  0
  4

Recursion terminates.


C functions:

// function to print the top-right peel of the matrix and 
// recursively call the print bottom-left on the submatrix.
void printTopRight(int a[][COL], int x1, int y1, int x2, int y2) {
    int i = 0, j = 0;

    // print values in the row.
    for(i = x1; i<=x2; i++) {
        printf("%d ", a[y1][i]);
    }

    // print values in the column.
    for(j = y1 + 1; j <= y2; j++)         {
        printf("%d ", a[j][x2]);
    }

    // see if more layers need to be printed.
    if(x2-x1 > 0) {
        // if yes recursively call the function to 
        // print the bottom left of the sub matrix.
        printBottomLeft(a, x1, y1 + 1, x2-1, y2);
    }
}

// function to print the bottom-left peel of the matrix and 
// recursively call the print top-right on the submatrix.
void printBottomLeft(int a[][COL], int x1, int y1, int x2, int y2) {
    int i = 0, j = 0;

    // print the values in the row in reverse order.
    for(i = x2; i>=x1; i--) {
        printf("%d ", a[y2][i]);
    }

    // print the values in the col in reverse order.
    for(j = y2 - 1; j >= y1; j--) {
        printf("%d ", a[j][x1]);
    }

    // see if more layers need to be printed.
    if(x2-x1 > 0) {
        // if yes recursively call the function to 
        // print the top right of the sub matrix.
        printTopRight(a, x1+1, y1, x2, y2-1);
    }
}

void printSpiral(int arr[][COL]) {
    printTopRight(arr,0,0,COL-1,ROW-1);
    printf("\n");
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
codaddict
  • 445,704
  • 82
  • 492
  • 529
  • 2
    excuse me but may i know what is the logic behind the x2 - x1? – Sikret Miseon Oct 21 '11 at 09:05
  • If x2 represents the rightmost column index and x1 represents the leftmost column index the check against x2-x1 > 0 determines whether there are any columns remaining to print out. If x2-x1=0 as in the last step in the example: [0 4] then there was only 1 column remaining which you just printed and the function should terminate. – Bauhaus Apr 12 '13 at 05:01
  • for M * N we need to check for the maximum between row and column. then it will work for ant matrix. thanks. – Trying Jul 20 '13 at 22:50
  • 2
    @codaddict shouldn't it be y2-y1 as the stopping condition in the printBottomLeft function – ordinary Sep 22 '13 at 07:24
  • 2
    With a matrix rotate, it becomes even simpler: Print the top row, then call the function with the remaining rows, rotated counter-clockwise. Recursion is done when there are no rows. – Wayne Conrad Dec 30 '13 at 02:17
  • recursion base case is wrong. this algorithm fails if number of columns are greater than number of rows, base case in printTopRight should be if (x2- x1> 0 && y1!=y2). I have ported this code to C# in my answer with correct base case and text case to make it work for any `n x m` matrix – Abdul Rauf Sep 05 '17 at 04:11
  • Nice way of approaching the problem, you can also decompose the problem into steps: go-right (until you reach the matrix boundary), go-down, go-left, go-up (repeat), of course if you just do only this you will run in circles, so you need to consider how far you go each time. For a matrix of size NxM, Start with left-boundary = 0, right-boundary = M-1, up-boundary = 1 (yes not 0), down-boundary = N-1. Now the idea is: Repeat: go-right(); right-boundary--; go-down(); down-boundary--; go-left(); left-boundary++; go-up(); up-boundary++; Until you cannot move. – j_s Aug 17 '18 at 07:29
34
  1. Pop top row
  2. Transpose and flip upside-down (same as rotate 90 degrees counter-clockwise)
  3. Go to 1

Python 2 code:

import itertools

arr = [[1,2,3,4],
       [12,13,14,5],
       [11,16,15,6],
       [10,9,8,7]]

def transpose_and_yield_top(arr):
    while arr:
        yield arr[0]
        arr = list(reversed(zip(*arr[1:])))

print list(itertools.chain(*transpose_and_yield_top(arr)))

For python 3x:

import itertools

arr = [[1,2,3,4],
       [12,13,14,5],
       [11,16,15,6],
       [10,9,8,7]]

def transpose_and_yield_top(arr):
while arr:
    yield arr[0]
    arr = list(reversed(list(zip(*arr[1:]))))


print(list(itertools.chain(*transpose_and_yield_top(arr))))
Ajay Gujja
  • 99
  • 1
  • 8
Rick S
  • 341
  • 3
  • 2
24

I see that no one has use only one for loop and without recursion in the code, and so I want to contribute.

The idea is like this:

Imagine there is a turtle standing at point (0,0), that is, top-left corner, facing east (to the right)

It will keep going forward and each time it sees a sign, the turtle will turn right

So if we put the turtle at point (0,0) facing right-ward, and if we place the signs at appropriate places, the turtle will traverse the array in spiral way.

Now the problem is: "Where to put the signs?"

Let's see where we should put the signs (marked by #, and numbers by O):

For a grid that looks like this:
O O O O
O O O O
O O O O
O O O O

We put the signs like this:
O O O #
# O # O
O # # O
# O O #

For a grid that looks like this:
O O O
O O O
O O O
O O O

We put the signs like this:
O O #
# # O
O # O
# O #

And for a grid that looks like this:
O O O O O O O
O O O O O O O
O O O O O O O
O O O O O O O
O O O O O O O

We put the signs like this:
O O O O O O #
# O O O O # O
O # O O # O O
O # O O O # O
# O O O O O #

We can see that, unless the point is at the top-left part, the signs are places at points where the distances to the closest horizontal border and the closest vertical border are the same, while for the top-left part, the distance to the top border is one more than the distance to the left border, with priority given to top-right in case the point is horizontally centered, and to top-left in case the point is vertically centered.

This can be realized in a simple function quite easily, by taking the minimum of (curRow and height-1-curRow), then the minimum of (curCol and width-1-curCol) and compare if they are the same. But we need to account for the upper-left case, that is, when the minimum is curRow and curCol themselves. In that case we reduce the vertical distance accordingly.

Here is the C code:

#include <stdio.h>

int shouldTurn(int row, int col, int height, int width){
    int same = 1;
    if(row > height-1-row) row = height-1-row, same = 0; // Give precedence to top-left over bottom-left
    if(col >= width-1-col) col = width-1-col, same = 0; // Give precedence to top-right over top-left
    row -= same; // When the row and col doesn't change, this will reduce row by 1
    if(row==col) return 1;
    return 0;
}

int directions[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
void printSpiral(int arr[4][4], int height, int width){
    int directionIdx=0, i=0;
    int curRow=0, curCol=0;
    for(i=0; i<height*width; i++){
        printf("%d ",arr[curRow][curCol]);
        if(shouldTurn(curRow, curCol, height, width)){
            directionIdx = (directionIdx+1)%4;
        }
        curRow += directions[directionIdx][0];
        curCol += directions[directionIdx][1];
    }
    printf("\n");
}

int main(){
    int arr[4][4]= {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
    printSpiral(arr, 4, 4);
    printSpiral(arr, 3, 4);
}

Which outputs:

1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
1 2 3 4 8 12 11 10 9 5 6 7
Community
  • 1
  • 1
justhalf
  • 8,960
  • 3
  • 47
  • 74
  • Nice idea. In this case this array is sorted from left to right and top to bottom. If that's the case can this solution be optimized further? – yalkris Sep 03 '14 at 01:14
  • What does sorted array have to do with this? We will still need to print in spiral way, right? – justhalf Sep 03 '14 at 01:24
  • You should change this line `row -= same;` to `if (same && (col != width -1 -col)) { row -= same;}` – yalkris Sep 03 '14 at 05:09
  • Why should I make a line longer? It's currently correct (as you can see from the output), since the value of `same` would have been updated to `0` when it's not in the upper-left section. – justhalf Sep 03 '14 at 05:15
  • 1
    To give top right more priority than top left. Try {{1,2,3},{4,5,6},{7,8,9},{10,11,12}}. You should turn at 5 but with your logic above shouldTurn returns 0 for row = 1 and column = 1. – yalkris Sep 03 '14 at 05:21
  • I see. In that case, we just need to update the previous row to `if(col >= width-1-col)`. Thanks @anonymous_123 – justhalf Sep 03 '14 at 06:22
  • @justhalf I cannot understand the logic behind declaring 'directions' array, how did you arrive at those numbers inside the array? Can you please explain? – Arif Nadeem Nov 07 '16 at 19:20
  • 1
    @ArifNadeem: Hi Arif, the `directions` array is an array of four (4) elements, each specifying a direction in the coordinate: RIGHT (0,1), DOWN (1,0), LEFT (0,-1), UP (-1,0). This is because when you move RIGHT, for example, you will not change the row (first number in the pair is 0) but you will increase the column number (second number in the pair is 1). Similarly for the other three pairs. You can see how these numbers are used in the lines containing `curRow += directions[directionIdx][0]` and `curCol += directions[directionIdx][1]`. Note that row numbers are increasing when you go down. – justhalf Nov 08 '16 at 02:11
  • @justhalf Thanks for the clear explanation, this solution is brilliant; much better than O(n^2) solutions in other answers. – Arif Nadeem Nov 08 '16 at 06:13
  • 1
    @ArifNadeem: Thanks for the compliment. However, this algorithm, or any algorithm for that matter, is at least O(n^2), since it needs to visit all entries in the array. =) – justhalf Nov 08 '16 at 08:19
  • Yes I realised that just now, but single loop makes it way clearer! Thanks :) – Arif Nadeem Nov 08 '16 at 10:17
8

Here are the three interesting ways

  1. Reading in spiral way can be treated like a snake moving towards boundary and turning on hitting the boundary or itself (I find it elegant and most efficient being a single loop of N iterations)

    ar = [
         [ 0,  1,  2,  3, 4],
         [15, 16, 17, 18, 5],
         [14, 23, 24, 19, 6],
         [13, 22, 21, 20, 7],
         [12, 11, 10, 9, 8]]
    
    def print_spiral(ar):
        """
        assuming a rect array
        """
        rows, cols = len(ar), len(ar[0])
        r, c = 0, -1 # start here
        nextturn = stepsx = cols # move so many steps
        stepsy = rows-1
        inc_c, inc_r = 1, 0 # at each step move this much
        turns = 0 # how many times our snake had turned
        for i in range(rows*cols):
            c += inc_c
            r += inc_r 
    
            print ar[r][c],
    
            if i == nextturn-1:
                turns += 1
                # at each turn reduce how many steps we go next
                if turns%2==0:
                    nextturn += stepsx
                    stepsy -= 1
                else:
                    nextturn += stepsy
                    stepsx -= 1
                # change directions
                inc_c, inc_r = -inc_r, inc_c  
    
    print_spiral(ar)
    

output:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
  1. A recursive approach would be to print outer layer and call same function for inner rectangle e.g.

    def print_spiral(ar, sr=0, sc=0, er=None, ec=None):
        er = er or len(ar)-1
        ec = ec or len(ar[0])-1
    
        if sr > er or sc > ec:
            print
            return
    
        # print the outer layer
        top, bottom, left, right = [], [], [], []
        for c in range(sc,ec+1):
            top.append(ar[sr][c])
            if sr != er:
                bottom.append(ar[er][ec-(c-sc)])
    
        for r in range(sr+1,er):
            right.append(ar[r][ec])
            if ec != sc:
                left.append(ar[er-(r-sr)][sc])
    
        print " ".join([str(a) for a in top + right + bottom + left]),
    
        # peel next layer of onion
        print_spiral(ar, sr+1, sc+1, er-1, ec-1)
    

Finally here is a small snippet to do it, not efficient but fun :), basically it prints top row, and rotates whole rectangle anti-clockwise and repeats

def print_spiral(ar):
    if not ar: return
    print " ".join(str(a) for a in ar[0]),
    ar = zip(*[ reversed(row) for row in ar[1:]])
    print_spiral(ar)
Anurag Uniyal
  • 85,954
  • 40
  • 175
  • 219
  • 1
    I just realize that this is similar to what I'm trying to achieve, but I used different method to find out when to turn. Counting the number of steps is a good idea, too! – justhalf Sep 03 '14 at 01:33
6

This program works for any n*n matrix..

public class circ {
    public void get_circ_arr (int n,int [][] a)
    {
        int z=n;
        {
            for (int i=0;i<n;i++)
            {
                for (int l=z-1-i;l>=i;l--)
                {
                    int k=i;
                    System.out.printf("%d",a[k][l]);
                }           

                for (int j=i+1;j<=z-1-i;j++)
                {
                    int k=i;
                    {
                        System.out.printf("%d",a[j][k]);
                    }
                }

                for (int j=i+1;j<=z-i-1;j++)
                {
                    int k=z-1-i;
                    {
                        System.out.printf("%d",a[k][j]);
                    }
                }

                for (int j=z-2-i;j>=i+1;j--)
                {
                    int k=z-i-1;        
                    {
                        System.out.printf("%d",a[j][k]);
                    }
                }
            }
        }
    }
}

Hope it helps

madth3
  • 7,275
  • 12
  • 50
  • 74
Surendran
  • 71
  • 1
  • 3
5

I was obsessed with this problem when I was learning Ruby. This was the best I could do:

def spiral(matrix)
  matrix.empty? ? [] : matrix.shift + spiral(matrix.transpose.reverse)
end

You can check out some of my other solutions by stepping back through the revisions in this gist. Also, if you follow the link back to whom I forked the gist from, you'll find some other clever solutions. Really interesting problem that can be solved in multiple elegant ways — especially in Ruby.

O-I
  • 1,535
  • 1
  • 13
  • 13
3

JavaScript solution:

var printSpiral = function (matrix) {
  var i;
  var top = 0;
  var left = 0;
  var bottom = matrix.length;
  var right = matrix[0].length;

  while (top < bottom && left < right) {

    //print top 
    for (i = left; i < right; i += 1) {
      console.log(matrix[top][i]);
    }
    top++;

    //print right column
    for (i = top; i < bottom; i += 1) {
      console.log(matrix[i][right - 1]);
    }
    right--;

    if (top < bottom) {
      //print bottom
      for (i = right - 1; i >= left; i -= 1) {
        console.log(matrix[bottom - 1][i]);
      }
      bottom--;
    }

    if (left < right) {
      //print left column
      for (i = bottom - 1; i >= top; i -= 1) {
        console.log(matrix[i][left]);
      }
      left++;
    }
  }
};
spark
  • 79
  • 1
  • 1
2

Two dimensional N*N Matrix is Square matrix

Idea:

We have to traverse in four different directions to traverse like spiral. We have to traverse inside matrix once one layer of spiral is over. So total, we need 5 loops, 4 loops to traverse like spiral and 1 loop to traverse through the layers.

public void printSpiralForm(int[][] a, int length)
{

  for( int i = 0 , j = length-1 ; i < j ; i++ , j-- )
  {

    for( int k = i ; k < j ; k++ )
    {
      System.out.print( a[i][k] + " " ) ;
    }

    for( int k = i ; k < j ; k++ )
    {
      System.out.print(a[k][j] + " ");
    }

    for( int k = j ; k > i ; k-- )
    {
      System.out.print(a[j][k] + " ") ;
    }

    for( int k = j ; k > i ; k-- )
    {
      System.out.print( a[k][i] + " " ) ;
    }

  }

  if ( length % 2 == 1 )
  {
    System.out.println( a[ length/2 ][ length/2 ] ) ;
  }

}
Billz
  • 7,879
  • 7
  • 33
  • 35
  • If you remove the `{}`, the code will be neatest, like here http://www.crazyforcode.com/print-square-matrix-spiral-form/ – Jackson Tale Mar 04 '15 at 10:18
2

Given a matrix of chars, implement a method that prints all characters in the following order: first the outer circle, then the next one and so on.

public static void printMatrixInSpiral(int[][] mat){

    if(mat.length == 0|| mat[0].length == 0){
        /* empty matrix */
        return;
    }

    StringBuffer str = new StringBuffer();
    int counter = mat.length * mat[0].length;
    int startRow = 0;
    int endRow = mat.length-1;
    int startCol = 0;
    int endCol = mat[0].length-1;
    boolean moveCol = true;
    boolean leftToRight = true;
    boolean upDown = true;

    while(counter>0){

        if(moveCol){

            if(leftToRight){

                /* printing entire row left to right */                 
                for(int i = startCol; i <= endCol ; i++){                       
                    str.append(mat[startRow][i]);
                    counter--;
                }
                leftToRight = false;
                moveCol = false;
                startRow++;
            }
            else{

                /* printing entire row right to left */
                for(int i = endCol ; i >= startCol ; i--){
                    str.append(mat[endRow][i]);
                    counter--;
                }
                leftToRight = true;
                moveCol = false;
                endRow--;       
            }
        }
        else
        {
            if(upDown){                 

                /* printing column up down */
                for(int i = startRow ; i <= endRow ; i++){                      
                    str.append(mat[i][endCol]);
                    counter--;
                }
                upDown = false;
                moveCol = true;
                endCol--;
            }
            else
            {

                /* printing entire col down up */
                for(int i = endRow ; i >= startRow ; i--){
                    str.append(mat[i][startCol]);
                    counter--;
                }
                upDown = true;
                moveCol = true;
                startCol++;
            }
        }
    }
    System.out.println(str.toString());
}
Maya Raveh
  • 21
  • 1
2

Just keep it simple -->

public class spiralMatrix {

public static void printMatrix(int[][] matrix, int rows, int col)
{
    int rowStart=0;
    int rowEnd=rows-1;
    int colStart=0;
    int colEnd=col-1;

    while(colStart<=colEnd && rowStart<=rowEnd)
    {
        for(int i=colStart;i<colEnd;i++)
            System.out.println(matrix[rowStart][i]);

        for(int i=rowStart;i<rowEnd;i++)
            System.out.println(matrix[i][colEnd]);

        for(int i=colEnd;i>colStart;i--)
            System.out.println(matrix[rowEnd][i]);

        for(int i=rowEnd;i>rowStart;i--)
            System.out.println(matrix[i][colStart]);
        rowStart++;
        colEnd--;
        rowEnd--;
        colStart++;

    }

}
public static void main(String[] args){

    int[][] array={{1,2,3,4},{5,6,7,8}};
    printMatrix(array,2,4);
}

}

piyush121
  • 496
  • 11
  • 16
2

One solution involves directions right, left, up, down, and their corresponding limits (indices). Once the first row is printed, and direction changes (from right) to down, the row is discarded by incrementing the upper limit. Once the last column is printed, and direction changes to left, the column is discarded by decrementing the right hand limit... Details can be seen in the self-explanatory C code.

#include <stdio.h>
#define N_ROWS 5
#define N_COLS 3

void print_spiral(int a[N_ROWS][N_COLS])
{
    enum {up, down, left, right} direction = right;
    int up_limit = 0,
        down_limit = N_ROWS - 1,
        left_limit = 0,
        right_limit = N_COLS - 1,
        downcount = N_ROWS * N_COLS,
        row = 0,
        col = 0;

    while(printf("%d ", a[row][col]) && --downcount)
        if(direction == right)
        {
            if(++col > right_limit)
            {
                --col;
                direction = down;
                ++up_limit;
                ++row;
            }
        }
        else if(direction == down)
        {
            if(++row > down_limit)
            {
                --row;
                direction = left;
                --right_limit;
                --col;
            }
        }
        else if(direction == left)
        {
            if(--col < left_limit)
            {
                ++col;
                direction = up;
                --down_limit;
                --row;
            }
        }
        else /* direction == up */
            if(--row < up_limit)
            {
                ++row;
                direction = right;
                ++left_limit;
                ++col;
            }
}

void main()
{
    int a[N_ROWS][N_COLS] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
    print_spiral(a);
}

Link for Testing and Download

.

Apshir
  • 193
  • 8
1

This is my implementation:

public static void printMatrix(int matrix[][], int M, int N){
    int level = 0;
    int min = (M < N) ? M:N;
    System.out.println();
    while(level <= min/2){
        for(int j = level; j < N - level - 1; j++){
            System.out.print(matrix[level][j] + "\t");
        }
        for(int i = level; i < M - level - 1; i++) {
            System.out.print(matrix[i][N - level - 1] + "\t");
        }
        for(int j = N - level - 1; j > level; j--){
            System.out.print(matrix[M - level - 1][j] + "\t");
        }
        for(int i = M - level - 1; i > level; i-- ){
            System.out.print(matrix[i][level] + "\t");
        }
        level++;
    }
}
WonderLi
  • 31
  • 2
1

Here is my solution. Please correct if I'm wrong.

class Spiral:

def spiralOrder(self, A):
    result = []
    c = []
    c.append(A[0])
    b = A[1:]
    while len(b) > 0:
        b = self.rotate(b)
        c.append(b[0])
        b = b[1:]
    for item in c:
        for fitem in item:
            print fitem,
            result.append(fitem)
    return result

def rotate(self,a):
    b = []
    l = zip(*a)
    for i in xrange(len(l)-1,-1,-1):
        b.append(list(l[i]))
    return b

if __name__ == '__main__':
  a = [[1, 2, 3,3], [4, 5, 6,6], [7, 8, 9,10]]
  s = Spiral()
s.spiralOrder(a)
ksha
  • 2,007
  • 1
  • 19
  • 22
1

Slash Top Row -> Transpose -> Flip -> Repeat.

void slashTransposeFlip(int[][] m){

    if( m.length * m[0].length == 1){ //only one element left
        System.out.print(m[0][0]);
    }else{
        //print the top row
        for(int a:m[0]){System.out.print(a+" ");}

        //slash the top row from the matrix.
        int[][] n = Arrays.copyOfRange(m,1,m.length);

        int[][] temp = n;
        int rows = temp.length;
        int columns = temp[0].length;

        //invert rows and columns and create new array
        n = new int[columns][rows];

        //transpose
        for(int x=0;x<rows;x++)
            for(int y=0;y<columns;y++)
                n[y][x] = temp[x][y];

        //flipping time
        for (int i = 0; i < n.length / 2; i++) {
          int[] t = n[i];
          n[i] = n[n.length - 1 - i];
          n[n.length - 1 - i] = t;
        }

        //recursively call again the reduced matrix.
        slashTransposeFlip(n);
    }
}
Sorter
  • 9,704
  • 6
  • 64
  • 74
1

Complexity: Single traverse O(n)

Please let me add my single loop answer with complexity O(n). I have observed that during left-right and right-left traverse of the matrix, there is an increase and decrease by one respectively in the row-major index. Similarly, for the top-bottom and bottom-top traverse there is increase and decrease by n_cols. Thus I made an algorithm for that. For example, given a (3x5) matrix with entries the row-major indexes the print output is: 1,2,3,4,5,10,15,14,13,12,11,6,7,8,9.

             ------->(+1)
          ^ 1  2  3  4  5   |
(+n_cols) | 6  7  8  9  10  | (-n_cols)
          | 11 12 13 14 15  
            (-1)<-------

Code solution:

#include <iostream>
using namespace std;

int main() {
    // your code goes here

    bool leftToRight=true, topToBottom=false, rightToLeft=false, bottomToTop=false;
    int idx=0;
    int n_rows = 3;
    int n_cols = 5;
    int cnt_h = n_cols, cnt_v = n_rows, cnt=0;
    int iter=1;
    for (int i=0; i <= n_rows*n_cols + (n_rows - 1)*(n_cols - 1)/2; i++){

        iter++; 
        if(leftToRight){
            if(cnt >= cnt_h){ 
                cnt_h--; cnt=0;
                leftToRight = false; topToBottom = true; 
                //cout  << "Iter: "<< iter << " break_leftToRight"<<endl;
            }else{
                cnt++;
                idx++;
                //cout << "Iter: "<< iter <<" idx: " << idx << " cnt: "<< cnt << " cnt_h: "<< cnt_h<< endl;
                cout<< idx << endl;
            }
        }else if(topToBottom){
            if(cnt >= cnt_v-1){
                cnt_v--; cnt=0;  
                leftToRight = false; topToBottom = false; rightToLeft=true;
                //cout  << "Iter: "<< iter  << " break_topToBottom"<<endl;
            }else{
                cnt++;
                idx+=n_cols;
                //cout  << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_v: "<< cnt_h<< endl;
                cout << idx <<endl;
            }
        }else if(rightToLeft){
            if(cnt >= cnt_h){
                cnt_h--; cnt=0; 
                leftToRight = false; topToBottom = false; rightToLeft=false; bottomToTop=true;
                //cout  << "Iter: "<< iter  << " break_rightToLeft"<<endl;
                //cout<< idx << endl;
            }else{
                cnt++;
                idx--;
                //cout  << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_h: "<< cnt_h<< endl;
                cout << idx <<endl;
            }
        }else if(bottomToTop){
            if(cnt >= cnt_v-1){
                cnt_v--; cnt=0;
                leftToRight = true; topToBottom = false; rightToLeft=false; bottomToTop=false;
                //cout  << "Iter: "<< iter << " break_bottomToTop"<<endl;
            }else{
                cnt++;
                idx-=n_cols;
                //cout  << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_v: "<< cnt_h<< endl;
                cout<< idx << endl;
            }
        }

        //cout << i << endl;
    }


    return 0;
}
Darkmoor
  • 862
  • 11
  • 29
1
function spiral(a) {
  var s = [];
  while (a.length) {
    // concat 1st row, push last cols, rotate 180 (reverse inner/outer)...
    s = s.concat(a.shift());
    a = a
      .map(function(v) {
        s.push(v.pop());
        return v.reverse();
      })
      .reverse();
  }
  return s;
}
var arr = [
  [1, 2, 3, 4], 
  [12, 13, 14, 5], 
  [11, 16, 15, 6], 
  [10, 9, 8, 7]
];
console.log(spiral(arr));// -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
arr = [
  [0, 1, 2, 3, 4],
  [15, 16, 17, 18, 5],
  [14, 23, 24, 19, 6],
  [13, 22, 21, 20, 7],
  [12, 11, 10, 9, 8]
];
console.log(spiral(arr));// -> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
0

Here is my implementation in Java:

public class SpiralPrint {
static void spiral(int a[][],int x,int y){

    //If the x and y co-ordinate collide, break off from the function

    if(x==y)
        return;
    int i;

    //Top-left to top-right

    for(i=x;i<y;i++)
        System.out.println(a[x][i]);

    //Top-right to bottom-right 

    for(i=x+1;i<y;i++)
        System.out.println(a[i][y-1]);

    //Bottom-right to bottom-left

    for(i=y-2;i>=x;i--)
        System.out.println(a[y-1][i]);

    //Bottom left to top-left

    for(i=y-2;i>x;i--)
        System.out.println(a[i][x]);

    //Recursively call spiral

    spiral(a,x+1,y-1);

}

public static void main(String[] args) {

    int a[][]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
    spiral(a,0,4);
    /*Might be implemented without the 0 on an afterthought, all arrays will start at 0 anyways. The second parameter will be the dimension of the array*/ 

    }

}
bantini
  • 205
  • 1
  • 2
  • 9
0
//shivi..coding is adictive!!
#include<shiviheaders.h>
#define R 3
#define C 6
using namespace std;

void  PrintSpiral(int er,int ec,int arr[R][C])
{
    int sr=0,sc=0,i=0;


    while(sr<=er && sc<=ec)
    {
        for(int i=sc;i<=ec;++i)
            cout<<arr[sr][i]<<" ";
        ++sr;

        for(int i=sr;i<=er;++i) 
            cout<<arr[i][ec]<<" ";
        ec--;

        if(sr<=er)  
        {
            for(int i=ec;i>=sc;--i)
                cout<<arr[er][i]<<" ";
            er--;   
        }

        if(sc<=ec)
        {
            for(int i=er;i>=sr;--i)
                cout<<arr[i][sc]<<" ";
            ++sc;   
        }

    }

}

int main()
{
    int a[R][C] = { {1,  2,  3,  4,  5,  6},
            {7,  8,  9,  10, 11, 12},
            {13, 14, 15, 16, 17, 18}
        };

        PrintSpiral(R-1, C-1, a);
}
Shivendra
  • 1,542
  • 2
  • 22
  • 35
0

int N = Integer.parseInt(args[0]);

    // create N-by-N array of integers 1 through N
    int[][] a = new int[N][N];
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            a[i][j] = 1 + N*i + j;

    // spiral
    for (int i = N-1, j = 0; i > 0; i--, j++) {
          for (int k = j; k < i; k++) System.out.println(a[j][k]);
          for (int k = j; k < i; k++) System.out.println(a[k][i]);
          for (int k = i; k > j; k--) System.out.println(a[i][k]);
          for (int k = i; k > j; k--) System.out.println(a[k][j]);
   }

   // special case for middle element if N is odd
   if (N % 2 == 1) System.out.println(a[(N-1)/2][(N-1)/2]);
}

}

0

Java code if anybody is interested.
Input:
4
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7

Output: 1 2 3 4 8 3 7 6 5 4 9 5 6 7 2 1

public class ArraySpiralPrinter {

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt(); //marrix size
    //read array
    int[][] ar = new int[n][n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        ar[i][j] = sc.nextInt();
      }
    }
    printTopRight(0, 0, n - 1, n - 1, ar);
  }
    //prints top and right layers.
  //(x1,y1) to (x1, y2) - top layer & (x1,y2) to (x2, y2)
  private static void printTopRight(int x1, int y1, int x2, int y2, int[][] ar) {
    //print row values - top
    for (int y = y1; y <= y2; y++) {
      System.out.printf("%d ", ar[x1][y]);
    }
    //print column value - right
    for (int x = x1 + 1; x <= x2; x++) {
      System.out.printf("%d ", ar[x][y2]);
    }

    //are there any remaining layers
    if (x2 - x1 > 0) {
      //call printBottemLeft
      printBottomLeft(x1 + 1, y1, x2, y2 - 1, ar);
    }
  }

    //prints bottom and left layers in reverse order
  //(x2,y2) to (x2, y1) - bottom layer & (x2,y1) to (x1, y1)
  private static void printBottomLeft(int x1, int y1, int x2, int y2, int[][] ar) {
    //print row values in reverse order - bottom
    for (int y = y2; y >= y1; y--) {
      System.out.printf("%d ", ar[x2][y]);
    }

    //print column value in reverse order - left
    for (int x = x2-1; x >= x1; x--) {
      System.out.printf("%d ", ar[x][y1]);
    }

    //are there any remaining layers
    if (x2 - x1 > 0) {
      printTopRight(x1, y1 + 1, x2 - 1, y2, ar);
    }
  }
}
0

This is a recursive version in C that I could think of:-

void printspiral  (int[][100],int, int, int, int);

int main()
{
  int r,c, i, j;
  printf ("Enter the dimensions of the matrix");
  scanf("%d %d", &r, &c);
  int arr[r][100];
  int min = (r<c?r:c);
  if (min%2 != 0) min = min/2 +1;
  for (i = 0;i<r; i++)
    for (j = 0; j<c; j++)
        scanf ("%d",&arr[i][j]);

  printspiral(arr,0,r,c,min );


}

void printspiral (int arr[][100], int i, int j, int k, int min)
{
   int a;

   for (a = i; a<k;a++)
   printf("%d\n", arr[i][a]);
   for (a=i+1;a<j;a++) 
   printf ("%d\n", arr[a][k-1]);
   for (a=k-2; a>i-1;a--)
   printf("%d\n", arr[j-1][a]);
   for (a=j-2; a>i; a--)
   printf("%d\n", arr[a][i]);
   if (i < min)
       printspiral(arr,i+1, j-1,k-1, min);

 }
whizvids
  • 248
  • 2
  • 8
0

http://www.technicalinterviewquestions.net/2009/03/print-2d-array-matrix-spiral-order.html

here is the best explanation for the above answer :) along with diagram :)

Priyanka
  • 307
  • 2
  • 16
0
public static void printSpiral1(int array[][],int row,int col){

    int rowStart=0,colStart=0,rowEnd=row-1,colEnd=col-1;
    int i;

    while(rowStart<=rowEnd && colStart<= colEnd){

        for(i=colStart;i<=colEnd;i++)
            System.out.print(" "+array[rowStart][i]);   

        for(i=rowStart+1;i<=rowEnd;i++)
            System.out.print(" "+array[i][colEnd]); 

        for(i=colEnd-1;i>=colStart;i--)
            System.out.print(" "+array[rowEnd][i]); 

        for(i=rowEnd-1;i>=rowStart+1;i--)
            System.out.print(" "+array[i][colStart]);   

        rowStart++;
        colStart++;
        rowEnd--;
        colEnd--;
    }

}
Akhilesh Dhar Dubey
  • 2,152
  • 2
  • 25
  • 39
0
public class SpiralPrint{

    //print the elements of matrix in the spiral order.
    //my idea is to use recursive, for each outer loop

    public static void printSpiral(int[][] mat, int layer){
        int up = layer;
        int buttom = mat.length - layer - 1;
        int left = layer;
        int right = mat[0].length - layer - 1;
        if(up > buttom+1 || left > right + 1)
            return; // termination condition

        //traverse the other frame, 
        //print up
        for(int i = left; i <= right; i ++){
            System.out.print( mat[up][i]+ " " );
        }
        //print right
        for(int i = up + 1; i <=buttom; i ++){
            System.out.print(mat[i][right] + " ");
        }

        //print buttom
        for(int i = right - 1; i >= left; i --){
            System.out.print(mat[buttom][i] + " ");
        }

        //print left
        for(int i = buttom - 1; i > up; i --){
            System.out.print(mat[i][left] + " ");
        }

        //recursive call for the next level
        printSpiral(mat, layer + 1);
    }

    public static void main(String[] args){

        int[][] mat = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16}};
        int[][] mat2 = {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}};
        SpiralPrint.printSpiral(mat2,0);
        return;
    }
}
Mr X
  • 1,637
  • 3
  • 29
  • 55
0

Here is my solution in C#:

public static void PrintSpiral(int[][] matrix, int n)
{
    if (matrix == null)
    {
        return;
    }

    for (int layer = 0; layer < Math.Ceiling(n / 2.0); layer++)
    {
        var start = layer;
        var end = n - layer - 1;
        var offset = end - 1;

        Console.Write("Layer " + layer + ": ");

        // Center case
        if (start == end)
        {
            Console.Write(matrix[start][start]);
        }

        // Top
        for (int i = start; i <= offset; i++)
        {
            Console.Write(matrix[start][i] + " ");
        }

        // Right
        for (int i = start; i <= offset; i++)
        {
            Console.Write(matrix[i][end] + " ");
        }

        // Bottom
        for (int i = end; i > start; i--)
        {
            Console.Write(matrix[end][i] + " ");
        }

        // Left
        for (int i = end; i > start; i--)
        {
            Console.Write(matrix[i][start] + " ");
        }

        Console.WriteLine();
    }
}
MattMacdonald
  • 93
  • 1
  • 1
  • 9
0

Here's my approach using an Iterator . Note this solves almost the same problem.. Complete code here : https://github.com/rdsr/algorithms/blob/master/src/jvm/misc/FillMatrix.java

import java.util.Iterator;

class Pair {
    final int i;
    final int j;

    Pair(int i, int j) {
        this.i = i;
        this.j = j;
    }

    @Override
    public String toString() {
        return "Pair [i=" + i + ", j=" + j + "]";
    }
}


enum Direction {
    N, E, S, W;
}


class SpiralIterator implements Iterator<Pair> {
    private final int r, c;
    int ri, ci;
    int cnt;

    Direction d; // current direction
    int level; // spiral level;

    public SpiralIterator(int r, int c) {
        this.r = r;
        this.c = c;

        d = Direction.E;
        level = 1;
    }

    @Override
    public boolean hasNext() {
        return cnt < r * c;
    }

    @Override
    public Pair next() {
        final Pair p = new Pair(ri, ci);
        switch (d) {
            case E:
                if (ci == c - level) {
                    ri += 1;
                    d = changeDirection(d);
                } else {
                    ci += 1;
                }
                break;

            case S:
                if (ri == r - level) {
                    ci -= 1;
                    d = changeDirection(d);
                } else {
                    ri += 1;
                }
                break;

            case W:
                if (ci == level - 1) {
                    ri -= 1;
                    d = changeDirection(d);
                } else {
                    ci -= 1;
                }
                break;

            case N:
                if (ri == level) {
                    ci += 1;
                    level += 1;
                    d = changeDirection(d);
                } else {
                    ri -= 1;
                }
                break;
        }

        cnt += 1;
        return p;
    }

    private static Direction changeDirection(Direction d) {
        switch (d) {
            case E:
                return Direction.S;
            case S:
                return Direction.W;
            case W:
                return Direction.N;
            case N:
                return Direction.E;
            default:
                throw new IllegalStateException();
        }
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }

}


public class FillMatrix {
    static int[][] fill(int r, int c) {
        final int[][] m = new int[r][c];
        int i = 1;
        final Iterator<Pair> iter = new SpiralIterator(r, c);
        while (iter.hasNext()) {
            final Pair p = iter.next();
            m[p.i][p.j] = i;
            i += 1;
        }
        return m;
    }

    public static void main(String[] args) {
        final int r = 19, c = 19;
        final int[][] m = FillMatrix.fill(r, c);
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                System.out.print(m[i][j] + " ");
            }
            System.out.println();
        }
    }
}
RD.
  • 300
  • 4
  • 12
0

Complete pure C program for any 2D array matrix with given row x column.

#include <stdio.h>
void  printspiral(int *p,int r, int c) {    
    int i=0,j=0,m=1,n=0;
    static int firstrun=1,gCol;
    if (!p||r<=0||c<=0)
        return ;
    if(firstrun) {
        gCol=c;
        firstrun=0;
    }
    for(i=0,j=0;(0<=i && i<c)&&(0<=j && j<r);i+=m,j+=n) {                                                                               
        printf(" %d",p[i+j*gCol]);                                                                                                      
        if (i==0 && j==1 && (i+1)!=c) break;                                                                                            
        else if (i+1==c && !j) {m=0;n=1;}                                                                                               
        else if (i+1==c && j+1==r && j) {n=0;m=-1;}                                                                                     
        else if (i==0 && j+1==r && j) {m=0;n=-1;}                                                                                       
    }                                                                                                                                   
    printspiral(&p[i+j*gCol+1],r-2,c-2);                                                                                                
    firstrun=1;                                                                                                                         
    printf("\n");                                                                                                                       
}                                                                                                                                       
int main() {                                                                                                                            
    int a[3][3]={{0,1,2},{3,4,5},{6,7,8}};                                                                                              
    int b[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};                                                                                      
    int c[4][3]={{0,1,2},{3,4,5},{6,7,8},{9,10,11}};                                                                                    
    int d[3][1]={{0},{1},{2}};                                                                                                          
    int e[1][3]={{0,1,2}};                                                                                                              
    int f[1][1]={{0}};                                                                                                                  
    int g[5][5]={{0,1,2,3,4},{5,6,7,8,9},{10,11,12,13,14},{15,16,17,18,19},{20,21,22,23,24}};
    printspiral(a,3,3);                                                                                                                 
    printspiral(b,3,4);                                                                                                                 
    printspiral(c,4,3);                                                                                                                 
    printspiral(d,3,1);                                                                                                                 
    printspiral(e,1,3);                                                                                                                 
    printspiral(f,1,1);                                                                                                                 
    printspiral(g,5,5);
    return 0;                                                                                                                           
}
Balamurugan A
  • 1,886
  • 2
  • 17
  • 19
0

This question is related to this one: Matrix arrangement issues in php

The answers presented seem to work but are complicated to understand. A very simple way to solve this is divide and conquer i.e., after reading the edge, remove it and the next read will be much simpler. Check out a complete solution in PHP below:

#The source number matrix
$source[0] = array(1, 2, 3, 4);
$source[1] = array(5, 6, 7, 8);
$source[2] = array(9, 10, 11, 12);
$source[3] = array(13, 14, 15, 16);
$source[4] = array(17, 18, 19, 20);

#Get the spiralled numbers
$final_spiral_list = get_spiral_form($source);
print_r($final_spiral_list);


function get_spiral_form($matrix)
{
    #Array to hold the final number list
    $spiralList = array();

    $result = $matrix;
    while(count($result) > 0)
    {
        $resultsFromRead = get_next_number_circle($result, $spiralList);
        $result = $resultsFromRead['new_source'];
        $spiralList = $resultsFromRead['read_list'];
    }

    return $spiralList;
}


function get_next_number_circle($matrix, $read)
{
    $unreadMatrix = $matrix;

    $rowNumber = count($matrix);
    $colNumber = count($matrix[0]);

    #Check if the array has one row or column
    if($rowNumber == 1) $read = array_merge($read, $matrix[0]);
    if($colNumber == 1) for($i=0; $i<$rowNumber; $i++) array_push($read, $matrix[$i][0]);
    #Check if array has 2 rows or columns
    if($rowNumber == 2 || ($rowNumber == 2 && $colNumber == 2)) 
    {
        $read = array_merge($read, $matrix[0], array_reverse($matrix[1]));
    }

    if($colNumber == 2 && $rowNumber != 2) 
    {
        #First read left to right for the first row
        $read = array_merge($read, $matrix[0]);
        #Then read down on right column
        for($i=1; $i<$rowNumber; $i++) array_push($read, $matrix[$i][1]);
        #..and up on left column
        for($i=($rowNumber-1); $i>0; $i--) array_push($read, $matrix[$i][0]);
    }



    #If more than 2 rows or columns, pick up all the edge values by spiraling around the matrix
    if($rowNumber > 2 && $colNumber > 2)
    {
        #Move left to right
        for($i=0; $i<$colNumber; $i++) array_push($read, $matrix[0][$i]);
        #Move top to bottom
        for($i=1; $i<$rowNumber; $i++) array_push($read, $matrix[$i][$colNumber-1]);
        #Move right to left
        for($i=($colNumber-2); $i>-1; $i--) array_push($read, $matrix[$rowNumber-1][$i]);
        #Move bottom to top
        for($i=($rowNumber-2); $i>0; $i--) array_push($read, $matrix[$i][0]);
    }

    #Now remove these edge read values to create a new reduced matrix for the next read
    $unreadMatrix = remove_top_row($unreadMatrix);  

    $unreadMatrix = remove_right_column($unreadMatrix); 
    $unreadMatrix = remove_bottom_row($unreadMatrix);   
    $unreadMatrix = remove_left_column($unreadMatrix);  

    return array('new_source'=>$unreadMatrix, 'read_list'=>$read);
}


function remove_top_row($matrix)
{
    $removedRow = array_shift($matrix);
    return $matrix;
}

function remove_right_column($matrix)
{
    $neededCols = count($matrix[0]) - 1;
    $finalMatrix = array();
    for($i=0; $i<count($matrix); $i++) $finalMatrix[$i] = array_slice($matrix[$i], 0, $neededCols);
    return $finalMatrix;
}

function remove_bottom_row($matrix)
{
    unset($matrix[count($matrix)-1]);
    return $matrix;
}

function remove_left_column($matrix)
{
    $neededCols = count($matrix[0]) - 1;
    $finalMatrix = array();
    for($i=0; $i<count($matrix); $i++) $finalMatrix[$i] = array_slice($matrix[$i], 1, $neededCols);
    return $finalMatrix;
}
Community
  • 1
  • 1
Al Zziwa
  • 1,127
  • 9
  • 5
0
// Program to print a matrix in spiral order

#include <stdio.h>
int main(void) {
    // your code goes here
    int m,n,i,j,k=1,c1,c2,r1,r2;;
    scanf("%d %d",&m,&n);
    int a[m][n];
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    r1=0;
    r2=m-1;
    c1=0;
    c2=n-1;

    while(k<=m*n)
                {
                    for(i=c1;i<=c2;i++)
                    {
                        k++;
                        printf("%d ",a[r1][i]);
                    }

                    for(j=r1+1;j<=r2;j++)
                    {
                        k++;
                        printf("%d ",a[j][c2]);
                    }

                    for(i=c2-1;i>=c1;i--)
                    {
                        k++;
                        printf("%d ",a[r2][i]);
                    }

                    for(j=r2-1;j>=r1+1;j--)
                    {
                        k++;
                        printf("%d ",a[j][c1]);
                    }

                 c1++;
                 c2--;
                 r1++;
                 r2--;
                }
    return 0;
}
0

This is java implementation for any m x n matrix. Where rows = No. of rows and Column = No. of Columns

public static void printSpiral(int rows, int columns, int a[][])
    {
        int i, k = 0, l = 0;

        /*  k - starting row index
            l - starting column index
        */

        while (k < rows && l < columns)
        {
            /* Print the first row from the remaining rows */
            for (i = l; i < columns; ++i)
            {
                System.out.println(a[k][i]);
            }
            k++;

            /* Print the last column from the remaining columns */
            for (i = k; i < rows; ++i)
            {
                System.out.println(a[i][columns-1]);
            }
            columns--;

            /* Print the last row from the remaining rows */
            if ( k < rows)
            {
                for (i = columns-1; i >= l; --i)
                {
                    System.out.println(a[rows-1][i]);
                }
                rows--;
            }

            /* Print the first column from the remaining columns */
            if (l < columns)
            {
                for (i = rows-1; i >= k; --i)
                {
                    System.out.println(a[i][l]);
                }
                l++;    
            }        
        }
    }
anand mishra
  • 900
  • 1
  • 11
  • 30
  • That's seems like a copy of GFG code for peeling 2D array. You should've at least change those dumb variable name they gave, it's totally confusing. – Debu Shinobi Nov 25 '19 at 13:37
0
#include <iostream>

using namespace std;

const int MAX=100;

int main(void)
{
int a[MAX][MAX],i,j,lower,upper,k,n=0,am=0;
cout<<"enter number or size of matrix \n"<<endl;
cin>>n;

// assigning the value 
for(i=0;i<n;i++)
{
    for(j=0;j<n;j++)
      a[i][j]=am+1;

}
i=0;
j=0;
lower=0,upper=n-1;
for(k=0;k<(n*n);k++)
{
    cout<<a[i][j]<<"\t";
    if((i==lower)&&(j<upper))
            j++;
    else if((j==upper)&&(i<lower))
            j--;
    else if((j==lower)&&(i>lower))
           i--;
    if((a[i][j]==a[lower][i]))
    {
        lower++;
        upper--;
        i++;
        j++;
    }
}
return 0;
}
0

You can imagine that spiral consists of an ordered set of horizontal and vertical segments. You can also observe that each next horizontal segment is one element shorter that previous horizontal segment and each next vertical segment is one element shorter than previous vertical segment. Each next segment starts in a cell that is adjacent to cell where previous segment ends. I assume that we construct a spiral in a clockwise direction. First horizontal segment length equals to a number of columns in a given matrix. First vertical segment length equals to a number of rows in a given matrix minus one. Using these observations you can traverse any NxM matrix without any additional memory and recursion in O(NxM) running time:

public static void VisitBySpiral<T>(T[,] matrix, Action<T> onVisit)
{
    var spiralWidth = matrix.GetLength(1);
    var spiralHeight = matrix.GetLength(0);
    var row = 0;
    var column = 0;
    var step = +1;
    while (spiralWidth > 0 && spiralHeight > 0)
    {
        var horizontalSteps = spiralWidth;
        while (horizontalSteps-- > 0)
        {
            onVisit(matrix[row, column]);
            if (horizontalSteps > 0)
            {
                column += step;
            }
        }
        // Move to the cell where next vertical segment starts.
        row += step;
        --spiralHeight;

        var verticalSteps = spiralHeight;
        while (verticalSteps-- > 0)
        {
            onVisit(matrix[row, column]);
            if (verticalSteps > 0)
            {
                row += step;
            }
        }
        --spiralWidth;
        step *= -1;
        // Move to the cell where next horizontal segment starts.
        column += step;
    }
}
Leonid Vasilev
  • 11,910
  • 4
  • 36
  • 50
0

Working code in C# with relevant test cases. It works for any n x m matrix.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MatrixSpiralPrint
{
    class Matrix
    {
        int[,] mat;
        public Matrix(int[,] matrix)
        {
            mat = matrix;
        }
        void printHelper(int x)
        {
            Console.Write(string.Format("{0} ", x));
        }
        // print the top right of the matrix and 
        // recursively call the print bottom left on the submatrix.
        void printTopRight(int colStart, int rowStart, int colEnd, int rowEnd)
        {
            int i = 0, j = 0;

            // print Top row.
            for (i = colStart; i <= colEnd; i++)
            {
                printHelper(mat[rowStart, i]);
            }

            // print Right column.
            for (j = rowStart + 1; j <= rowEnd; j++)
            {
                printHelper(mat[j, colEnd]);
            }

            // Recursion base case: see if more layers need to be printed.
            if (colEnd - colStart > 0 && rowStart!=rowEnd)
            {
                // print the bottom left of the sub matrix.
                printBottomLeft(colStart, rowStart + 1, colEnd - 1, rowEnd);
            }
        }

        // print the bottom left peel of the matrix and 
        // recursively call the print top right on the submatrix.
        void printBottomLeft(int colStart, int rowStart, int colEnd, int rowEnd)
        {
            int i = 0, j = 0;

            // print Bottom row in reverse order.
            for (i = colEnd; i >= colStart; i--)
            {
                printHelper(mat[rowEnd, i]);
            }

            // print Left column in reverse order.
            for (j = rowEnd - 1; j >= rowStart; j--)
            {
                printHelper(mat[j, colStart]);
            }

            // Recursion base case: see if more layers need to be printed.
            if (colEnd - colStart > 0)
            {
                // print the top right of the sub matrix.
                printTopRight(colStart + 1, rowStart, colEnd, rowEnd - 1);
            }
        }

        void printMatrix()
        {
            int rowLength = mat.GetLength(0);
            int colLength = mat.GetLength(1);
            Console.WriteLine("Test Case");
            for (int i = 0; i < rowLength; i++)
            {
                for (int j = 0; j < colLength; j++)
                {
                    Console.Write(string.Format("{0} ", mat[i, j]));
                }
                Console.Write(Environment.NewLine + Environment.NewLine);
            }

        }
        public void printSpiral()
        {
            var maxRowIndex = mat.GetUpperBound(0);
            var maxColIndex = mat.GetUpperBound(1);
            printMatrix();
            Console.WriteLine("Spiral Print");
            printTopRight(0, 0, maxColIndex, maxRowIndex);
            Console.WriteLine("\n---------------------------------");
        }

    } 
    class Program
    {

        static void Main(string[] args)
        {
            var matrix = new int[,] {
                { 1,2,3,4,5},
                { 6,7,8,9,10},
                { 11,12,13,14,15},
                { 16,17,18,19,20},
                { 21,22,23,24,25}
            };
            var mat = new Matrix(matrix);
            mat.printSpiral();

            matrix = new int[,] {
                { 1,2,3,4},
                { 5,6,7,8},
                { 9,10,11,12}
            };
            mat = new Matrix(matrix);
            mat.printSpiral();

            matrix = new int[,] {
                { 1,2,3},
                { 4,5,6},
                { 7,8,9},
                { 10,11,12},
            };
            mat = new Matrix(matrix);
            mat.printSpiral();

            matrix = new int[,] {
                { 1,2 }
            };
            mat = new Matrix(matrix);
            mat.printSpiral();

            matrix = new int[,] {
                { 1},
                { 2}
            };
            mat = new Matrix(matrix);
            mat.printSpiral();
        }
    }
}

Note that accepted answer doesn't work from any n x m matrix. This code is ported to C# using code posted by @codaddict in the accepted answer. I have corrected recursion base case.

Abdul Rauf
  • 5,798
  • 5
  • 50
  • 70
0

I have solved the problem in Python3. It is passing almost all the edge cases.

def spiralOrder(self, matrix):
    r = len(matrix)
    if r == 0:
        return []

    c = len(matrix[0])

    result = []
    x = 0; y = 0
    while x< r and y<c:
        for i in range(y,c):
            result.append(matrix[x][i])
        x+=1
        for i in range(x,r):
            result.append(matrix[i][c-1])
        c-=1
        if x < r:
            for i in range(c-1,y-1,-1):
                result.append(matrix[r-1][i])
            r -=1
        if y <c :
            for i in range(r-1,x-1,-1):
                result.append(matrix[i][y])
            y+=1

    return result
Shagun Pruthi
  • 1,813
  • 15
  • 19
0

Here is a nice recursive solution in C++,

#include <iostream> 
#include <vector> 

using namespace std; 

void helper(const vector<vector<int>>& arr, vector<int>& spiral, int i, int j, int until, int i_, int j_) {
   int& comp = j_ != 0 ? j : i;  

   while(until != comp) {  
       spiral.push_back(arr.at(i).at(j)); 

       i += i_;     
       j += j_; 
   }  
} 

void get_spiral_ordering(vector<int>& spiral, const vector<vector<int>>& arr, int i, int until) {
    if(until == i) { 
       spiral.push_back(arr.at(i).at(i)); 
       return; 
    } else if(until < i) return;     

    helper(arr, spiral, i, i, until, 0, 1);   
    helper(arr, spiral, i, until, until, 1, 0);   
    helper(arr, spiral, until, until, arr.size()-1-until, 0, -1);   
    helper(arr, spiral, until, i, arr.size()-1-until, -1, 0);

    return get_spiral_ordering(spiral, arr, i+1, until-1);
}

To use this code, for any any nxn-dimensional array to get its spiral order, call get_spiral_ordering(result_vec, src, 0, src.size()-1)

Moshe Rabaev
  • 1,892
  • 16
  • 31
0

For printing a 2-D matrix consider matrix as a composition of rectangles and/or line where smaller rectangle is fitted into larger one, take boundary of matrix which forms a rectangle to be printed, starting with up-left element each time in each layer; once done with this go inside for next layer of smaller rectangle, in case i don't have a rectangle then it should be line to be printed, a horizontal or vertical. I have pasted the code with an example matrix, HTH.

#include <stdio.h>

int a[2][4] = { 1, 2 ,3, 44,
                8, 9 ,4, 55 };

void print(int, int, int, int);

int main() {

int row1, col1, row2, col2;

row1=0;
col1=0;
row2=1;
col2=3;


while(row2>=row1 && col2>=col1)
{
    print(row1, col1, row2, col2);

    row1++;
    col1++;
    row2--;
    col2--;
}

return 0;
}


void print(int row1, int col1, int row2, int col2) {

int i=row1;
int j=col1;

/* This is when single horizontal line needs to be printed */
if( row1==row2 && col1!=col2) {
    for(j=col1; j<=col2; j++)
        printf("%d ", a[i][j]);
    return;
}

/* This is when single vertical line needs to be printed */
if( col1==col2 && row1!=row2) {
    for(i=row1; j<=row2; i++)
        printf("%d ", a[i][j]);
    return;
}


/* This is reached when there is a rectangle to be printed */

for(j=col1; j<=col2; j++)
    printf("%d ", a[i][j]);

for(j=col2,i=row1+1; i<=row2; i++)
    printf("%d ", a[i][j]);

for(i=row2,j=col2-1; j>=col1; j--)
    printf("%d ", a[i][j]);

for(j=col1,i=row2-1; i>row1; i--)
    printf("%d ", a[i][j]);

}
Cleonjoys
  • 504
  • 4
  • 10
-1
    /// <param name="arr"></param>
    /// <param name="w">CONSTANT width</param>
    /// <param name="h">CONSTANT height of array</param>
    /// <param name="i">index or 1d array. At start is 0</param>
    /// <param name="n">number of printed elements. At start is 0</param>
    /// <param name="l">spiral loop. At start is 0</param>
    /// <param name="d">direction of iteration. At start is 1</param>
    /// <returns></returns>
    private int print(Array arr, int w, int h, int i, int n, int l, byte direction)
    {
        int x = i % w;
        int y = (i - x) / w;
        Console.Write(arr.GetValue(i) + " ");
        n++;
        if (n == arr.Length) return 0;

        switch (direction)
        {
            case 1://→
                if (x < w - l - 1)
                {
                    return print(arr, w, h, i + 1, n, l, 1);
                }
                return print(arr, w, h, i + w, n, l, 2);
            case 2://↓
                if (y < h - l - 1)
                {
                    return print(arr, w, h, i + w, n, l, 2);
                }
                return print(arr, w, h, i - 1, n, l, 3);
            case 3://←
                if (x > l)
                {
                    return print(arr, w, h, i - 1, n, l, 3);
                }
                return print(arr, w, h, i - w, n, l, 4);
            case 4://↑
                if (y > l + 1)
                {
                    return print(arr, w, h, i - w, n, l, 4);
                }
                return print(arr, w, h, i + 1, n, l + 1, 1);
            default:
                return 0;
        }
    }
user3526723
  • 101
  • 3
  • 2