$\large\color{red}\tau$ Given an 2D $m \times n$ array, print out the elements in spiral shape
e.g. \[ \begin{bmatrix} 1 & 2 & 3 & 4\\ 4 & 5 & 6 & 21\\ 7 & 8 & 9 & 11\\ \end{bmatrix} \] Output: [1 2 3 4 21 11 9 8 7 4 5 6]

1. If the 2D array is square matrix, then the algorithm is a bit easier
In fact, the probem is similar to [Rotate square matrix in counterclockwise 90 degrees]

but we assume $m \neq n$

There are two special cases that you need to pay attention to
1. when $ m \gt n$
$n$ will be decreased to 0 or 1 first
if $n == 1$
we just can print the inner vertical column

2. when $ m \lt n$
$m$ will be decreased to 0 or 1 first
if $m == 1$
we just can print the inner horizontal row


From the pictures, we can try to come up a skeleton algorithm
1. we need to walk
From left to right [1, 2, 3]
From top to bottom [4, 21]
From right to left [11, 9, 8]
From bottom to top [7, 4]
From left to right [5, 6]

In two dimensions array, the first index is moving vertically, and the second index is moving horizontally.
            
            int array[height][width];
            for(int k=0; k < height; k++) {
               for(int w=k; w < width-1-k; w++)
                   array[k][w]                      // left to right
               for(int h=k; h < height-1-k; h++)
                   array[h][width - 1 - k]          // top to bottom
               for(int w=k; w < width-1-k; w++)
                   array[width-1-w][height - 1 - k] // right to left
               for(int h=k; h < height-1-k; h++)
                   array[height - 1 -h][k]          // bottom to top
            }
            
// [1, 2]
    //
    // [1]
    // 
    // [1, 2]
    // [3, 4]
    // 
    // [1, 2, 3]
    // [4, 5, 6]
    // print spiral shape from rectangle 
    //
    public static void rotateRectangle(int[][] arr){
        if(arr != null){
            int height = arr.length;
            if(height > 0){
                int width = arr[0].length;
                int k = 0; 
                while(k < Math.min(height, width)){
                    if(width - 2*k == 1){
                        for(int i=k; i<height-k; i++){
                            Print.p(arr[i][k]);
                        } 
                        break;
                    }else if(height- 2*k == 1){
                        for(int i=k; i<width-k; i++){
                            Print.p(arr[k][i]);
                        }
                        break;
                    }
                    else if((width - 2*k == 0) || (height - 2*k == 0)){
                        break;
                    }else{
                        for(int i=k; i<width-1-k; i++){
                            Print.p(arr[k][i]);
                        } 
                        for(int i=k; i<height-1-k; i++){
                            Print.p(arr[i][width-1-k]);
                        }
                        for(int i=k; i<width-1-k; i++){
                            Print.p(arr[height-1-k][width-1-i]);
                        }
                        for(int i=k; i<height-1-k; i++){
                            Print.p(arr[height-1-i][k]);
                        }
                    }
                    k++;
                }
            }
        }
    }
//
    // [1]
    // [1, 2]
    // [3, 4]
    // [0][0] = 1
    // [0][1] = 2
    // [1][1] = 4
    // [1][0] = 3
    // k = 1
    //
    //
    // [1, 2, 3]
    // [4, 5, 6]
    // [7, 8, 9]
    // [1, 2] [3, 6] [9, 8] [7, 4]
    // [5]
    //
    // last update 
    // Tue Sep 27 02:24:44 PDT 2016
    // best working version
    public static void spiral2(int[][] arr, int k){
        if(arr != null && arr.length > 0){
            int h = arr.length;
            int w = arr[0].length;
            
            if(h - 2*k == 1){
                for(int i=k; i<w-k; i++){
                    Print.p(arr[k][i]);
                }
            }else if(w - 2*k == 1){
                for(int i=k; i<h-k; i++){
                    Print.p(arr[i][k]);
                }
            }else if(k < Math.min(h, w)/2){
                for(int i=k; i<w-1-k; i++){
                    Print.p(arr[k][i]);
                } 
                for(int i=k; i<h-1-k; i++){
                    Print.p(arr[i][w-1-k]);
                } 
                for(int i=k; i<w-1-k; i++){
                    Print.p(arr[h-1-k][w-1-i]);
                } 
                for(int i=k; i<h-1-k; i++){
                    Print.p(arr[h-1-i][k]);
                } 
                spiral2(arr, k+1);
            }
        }
    }