2d Array in Spiral Order

牧云@^-^@ 提交于 2019-11-28 05:59:08

问题


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]);
    }
  }
}

回答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);

}



回答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; 
}



回答3:


If you've figured out code to do the reads (for printing), then surely you can just modify that to do writes instead, using the same logic?

If you want each cell in the matrix to contain its "sequential number", counting backwards, something like this ought to work, assuming your access logic is correct:

for (int i = (m*n)-1, j = 0, index = m * n; i > 0; i--, j++) {
      for (int k = j; k < i; k++) values[j][j] = index--;
      for (int k = j; k < i; k++) values[k][i] = index--;
      for (int k = i; k > j; k--) values[i][k] = index--;
      for (int k = i; k > j; k--) values[k][j] = index--;
}



回答4:


Not the most efficient, but it should work: g is the array. I'm also using exceptions to control logic.

public static void spiralFill()
{
    x = (g.length-1)/2;
    y = (g[0].length-1)/2;

    try
    {
        while(true)
        {
             east();
             south();
             step++;
             west();
             north();
             step++;        
        }
    }
    catch(ArrayIndexOutOfBoundsException e)
    {

    }
}

public static void east()
{
for(int i = 0; i < step; i++)
{
        g[x][y] = count;
        count++;
    x++;
    }
}
public static void south()
{
    for(int i = 0; i < step; i++)
    {
        g[x][y] = count;
        count++;
        y--;
    }
}   
public static void west()
{
    for(int i = 0; i < step; i++)
    {
         g[x][y] = count;
         count++;
         x--;
    }
}   
public static void north()
{
   for(int i = 0; i < step; i++)
   {
       g[x][y] = count;
       count++;
       y++;
   }
}   



回答5:


Here is some of the variations:

public class SpiralMatrix {

    private static int[][] createSpiralMatrix(int size) {
        int[][] matrix = new int[size][size];

        int row = 0, col = -1;
        int value = 1;

        boolean horizontal = true;
        boolean increasing = true;
        boolean finish = false;

        while(!finish) {

            finish = true;
            if (horizontal && increasing) {
                while(tryAndSet(matrix, row, col + 1, value)) {
                    finish = false;
                    col++;
                    value++;
                }
            } else if (horizontal && !increasing) {
                while(tryAndSet(matrix, row, col - 1, value)) {
                    finish = false;
                    col--;
                    value++;
                }
            } else if (!horizontal && increasing) {
                while(tryAndSet(matrix, row + 1, col, value)) {
                    finish = false;
                    row++;
                    value++;
                }
            } else {
                while(tryAndSet(matrix, row - 1, col, value)) {
                    finish = false;
                    row--;
                    value++;
                }
            }

            if (!horizontal) {
                increasing = !increasing;
            }
            horizontal = !horizontal;
        }

        return matrix;
    }


    private static boolean tryAndSet(int[][] matrix, int row, int col, int value) {
        if (row < 0 || col < 0 || row >= matrix.length || col >= matrix[row].length || matrix[row][col] != 0) {
            return false;
        }
        matrix[row][col] = value;
        return true;
    }

    private static void printMatrix(int[][] matrix) {
        for (int i = 0; i < matrix.length; i++) {
            for(int j = 0; j < matrix[i].length; j++) {
                System.out.print("\t" + matrix[i][j]);
            }
            System.out.println();
        }
    }


    public static void main(String[] args) {
        try {
            int[][] spiralMatrix = createSpiralMatrix(40);
            printMatrix(spiralMatrix);
        } catch (Throwable th) {
            th.printStackTrace();
        }
    }



回答6:


public ArrayList<Integer> spiralOrder(final List<ArrayList<Integer>> a) {
     ArrayList<Integer> result = new ArrayList<Integer>();
      int m = a.get(0).size();
      int n = a.size();
      if(m>1 && n>1){
         int loopCounter = (n > m)  ? m*2 : n *2 -1 ;
         int opr=1;
         int i=0,j=0;
         int opA=m,opB=n,opC=0,opD=1;
         for(int k=0;k < loopCounter ;k++){
              if(opr == 1){
                 int counter =0;
                 while(counter < opA){
                    System.out.print(a.get(i).get(j)+ ";");
                    result.add(a.get(i).get(j));
                    counter++;

                    if(j != opA-1){
                        j++;
                    }
                    else{
                        break;
                    }
                 }
                 opr =2;
                 continue;
             }
             if(opr == 2){
                 i++;
                 int counter =1;
                 while(counter < opB){
                     System.out.print(a.get(i).get(j)+ ";");
                    result.add(a.get(i).get(j));
                    counter++;

                   if( i != opB-1){
                     i++;
                   }
                   else{
                       break;
                   }
                 }
                 opr =3;
                 continue;
             }
             if(opr == 3){
                 j--;
                 int counter =j;
                 while(counter >= opC){
                     System.out.print(a.get(i).get(j)+ ";");
                    result.add(a.get(i).get(j));
                    counter --;
                     if(j != opC){
                     j--;
                    }
                    else{
                        break;
                    }
                  }
                 opr =4;
                 continue;
             }
             if(opr == 4){
                 i--;
                 int counter = i;
                 while(counter >= opD){
                     System.out.print(a.get(i).get(j)+ ";");
                    result.add(a.get(i).get(j));
                    counter --;
                    if(i != opD){
                     i--;
                    }else{
                        break;
                    }
                 }
                 opr =1;
                 j++;
                 opA = opA -1;
                 opB = opB -1;
                 opC= opC +1;
                 opD = opD+1;
                 continue;
             }
         }

     }

         else if(n ==1){
              for(int k=0;k < a.get(0).size();k++){
                  result.add(a.get(0).get(k));
              }
         }

       else if(m==1 && n==1){
             result.add(a.get(0).get(0));
         }

     // Populate result;
     return result;

}



来源:https://stackoverflow.com/questions/945265/2d-array-in-spiral-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!