java 螺旋顺序的二维数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/945265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
2d Array in Spiral Order
提问by
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]);
}
}
}
回答by user763566
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);
}
回答by fuat
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.
下面的函数是一个大小为 N × N 的方阵,其中包含从 1 到 N * N 的整数,按螺旋顺序从左上角开始顺时针方向。
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;
}
回答by Foxz
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;
}
}
回答by unwind
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--;
}
回答by CookieOfFortune
Not the most efficient, but it should work: g is the array. I'm also using exceptions to control logic.
不是最有效的,但它应该有效:g 是数组。我也在使用异常来控制逻辑。
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++;
}
}
回答by djiva
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();
}
}

