2d Array in Spiral Order

18,783

Solution 1

int maxValue = target.length * target[0].length;

private int[][] generateMatrix(int[][] target, int level, int currentVal) {
    // always start from lower left corner in each layer
    int w = level;
    int h = target.length - level - 1;

    // fill the bottom line
    int i = 0;
    for (i = w; i < target[0].length - level && currentVal <= maxValue; i++) {
        target[h][i] = currentVal++;
    }

    w = target[0].length - level - 1;

    int j = 0;
    // fill the right line
    for (j = h - 1; j >= level && currentVal <= maxValue; j--) {
        target[j][w] = currentVal++;
    }

    h = level;

    // fill the above line
    for (i = w - 1; i >= level && currentVal <= maxValue; i--) {
        target[h][i] = currentVal++;
    }
    w = level;

    // fill the left line
    for (j = h + 1; j < target.length - level - 1 && currentVal <= maxValue; j++) {
        target[j][w] = currentVal++;
    }

    if (currentVal > maxValue)
        return target;
    return generateMatrix(target, ++level, currentVal);

}

Solution 2

Below function is a square matrix with a size N × N containing integers from 1 to N * N in a spiral order, starting from top-left and in clockwise direction.

int[][] spiralNumbers(int n) {
int[][] matrix = new int[n][n];
for (int step = 0, a = 0, size; step < n/2; step++) {
    size = (n - step * 2 - 1);
    for (int i = 0, chunk, chunkIndex, chunkOffset; i < 4 * size; i++) {
        chunk = i / size;
        chunkIndex = i % size;
        chunkOffset = n - step - 1;
        switch (chunk) {
            case 0:
                matrix[step][chunkIndex + step] = a+1;
                break;
            case 1:
                matrix[chunkIndex + step][chunkOffset] = a+1;
                break;
            case 2:
                matrix[chunkOffset][chunkOffset - chunkIndex] = a+1;
                break;
            case 3:
                matrix[chunkOffset - chunkIndex][step] = a+1;
                break;
            default:
                throw new IndexOutOfBoundsException();
        }
        a++;
    }
    if (n % 2 == 1) {
        matrix[n/2][n/2] = n * n;
    }
}
return matrix; 
}
Share:
18,783
apaderno
Author by

apaderno

I am a Drupal fan. I am a site moderator, user administrator, and Git administrator on Drupal.org. My task is blocking spammers, but also helping users with promoting their activity, their content, and the modules they host on Drupal.org.

Updated on June 07, 2022

Comments

  • apaderno
    apaderno almost 2 years

    I'm trying to fill an array in spiral order. So far, I can print the array in spiral order, but is there a way to modify the array so that i can fill it in spiral order and then just print the array? I'd like it to go in decreasing order like a countdown. Please help!

    public class Spiral {
      public static void main(int m, int n) { 
    
        // create m by n array of integers 1 through m*n
        int[][] values = new int[m][n];
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                values[i][j] = 1 + (m*n)*i + j;
    
        // spiral
        for (int i = (m*n)-1, j = 0; i > 0; i--, j++) {
              for (int k = j; k < i; k++) System.out.println(values[j][k]);
              for (int k = j; k < i; k++) System.out.println(values[k][i]);
              for (int k = i; k > j; k--) System.out.println(values[i][k]);
              for (int k = i; k > j; k--) System.out.println(values[k][j]);
        }
      }
    }
    
  • Admin
    Admin almost 15 years
    I keep getting an index out of bounds exception error on the 3rd for loop