问题
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