慕标5832272
根据您在我的第一个答案下的评论:我也在考虑另一种解决方案......使用 BFS。对于起始点,假设为 0,0,每次迭代总是深度为 1,因此如果从 0,0 开始,则执行 1,0 1,1 0,1,当到达行或列边界时,您会增加深度意味着在下一次迭代中您将使用 0,2 1,2 2,2 2,1 2,0 并且如果矩阵是 nxm 且 n!=m 您只需根据您所在的位置跳过列或行(检查矩阵总是绑定 m 和 n)。忘了说,这样它也适用于字母。我决定添加一个新答案而不是编辑第一个答案。由于我不太熟悉图和广度优先搜索,我无法为基于 BSF 的算法提供任何建议。但我想我理解你想要如何进行的想法,这是一个简单的实现方法。您希望在每次迭代中采取的步骤0,0-----0,11,11,0-----0,21,22,22,12,0-----0,31,32,33,33,23,13,0...无论矩阵是否是正方形,我最初都会关注正方形区域。例如,如果是一个4x6矩阵,我只看部分4x4,忽略最后两列。同样,如果行大于列。对于a,7x5我将查看5x5并忽略最后两行。在每次迭代中,我将使用两个内部循环,第一个循环增加行,第二个循环减少列。与之前的答案相反,这次我将使用字符串数组来完成您的评论:忘了说,这样它也适用于字母。static String[][] fillArray(int rows, int columns){ char ch = 'A'; String[][] matrix = new String[rows][columns]; int square = Math.min(rows, columns); for(int i = 0; i < square; i++){ String curr = String.valueOf(ch); for(int r = 0; r <= i ; r++){ matrix[r][i] = curr; } for(int c = i-1; c >= 0; c--){ matrix[i][c] = curr; } ch++; } return matrix;}例如使用 args 调用上述方法4x5public static void main(String[] args) { String[][] filled = fillArray(4,5); for(String[] row: filled){ System.out.println(Arrays.toString(row)); }}将导致[A, B, C, D, null][B, B, C, D, null][C, C, C, D, null][D, D, D, D, null]现在让我们看看仍然充满 的被忽略的区域null,即 的情况rows > columns or rows < columns。为了简单起见,我将用 填写此区域*。static String[][] fillArray(int rows, int columns){ char ch = 'A'; String[][] matrix = new String[rows][columns]; int square = Math.min(rows, columns); for(int i = 0; i < square; i++){ String curr = String.valueOf(ch); for(int r = 0; r <= i ; r++){ matrix[r][i] = curr; } for(int c = i-1; c >= 0; c--){ matrix[i][c] = curr; } ch++; } ch = '*'; if (rows > columns) { for (int i = square; i < rows; i++) { for (int j = 0; j < columns; j++) { matrix[i][j] = String.valueOf(ch); } } } if (rows < columns) { for (int i = square; i < columns; i++) { for (int j = 0; j < rows; j++) { matrix[j][i] = String.valueOf(ch); } } } return matrix;}调用 fillArray(4,6)public static void main(String[] args) { String[][] filled = fillArray(4,6); for(String[] row: filled){ System.out.println(Arrays.toString(row)); }}现在应该导致:[A, B, C, D, *, *][B, B, C, D, *, *][C, C, C, D, *, *][D, D, D, D, *, *]这篇文章比我实际想象的要长。但我希望它很容易理解。
萧十郎
如果您查看 nxn 矩阵,就会发现某种模式需要识别。 1 2 5 10 17 4 3 6 11 18 9 8 7 12 19 16 15 14 13 20 25 24 23 22 21 第一列中总是有平方数在第一行中,从最小的平方数 1 开始,添加奇数序列,即1,3,5,7,9,11 ....每行的模式[1] +1 +3 +5 +7 ....[4] -1 +3 +5 +7 ....[9] -1 -1 +5 +7 ....[16] -1 -1 -1 +7 ....[25] -1 -1 -1 -1 ....有了这些知识,现在就可以轻松填充n x n矩阵了。1创建一个包含从到 的奇数的列表columns-1,通过逐个添加列表的元素来填充第一行,每次迭代后将列表中的第 i 个数字替换为-1能够使用该行的列表i+1th。现在对于非方矩阵,可以使用上述方法填充矩阵的方区域,并分别处理剩余的行或列。找到正方形区域的大小以定义其余行/列的计数器相对简单。只要计算一下Math.pow(Math.min(rows, columns), 2);我采用了您的方法名称并稍微更改了您的打印方法。我没有评论代码,但希望清楚正在做什么。如果有任何不清楚的地方,请随时询问。import java.util.List;import java.util.stream.Collectors;import java.util.stream.IntStream;public class Test{ public static int matrix[][]; public static void main(String[] args) { borderLayout(5, 5); print(); } public static void borderLayout(int rows, int columns) { //create a list (1,3,5, ...) with size = columns - 1 List<Integer> list = IntStream.iterate(1, i -> i + 2) .limit(columns - 1).boxed() .collect(Collectors.toList()); matrix = new int[rows][columns]; int square = Math.min(rows, columns); for (int i = 0; i < square; i++) { int temp = (i + 1) * (i + 1); for (int j = 0; j < square; j++) { if (j == 0) { matrix[i][j] = temp; } else { matrix[i][j] = matrix[i][j - 1] + list.get(j - 1); } } if (i < columns - 1) { list.set(i, -1); } } if (rows > columns) { int counter = (int) Math.pow(Math.min(rows, columns), 2); int sqrt = (int) Math.sqrt(counter); for (int i = sqrt; i < rows; i++) { for (int j = 0; j < columns; j++) { matrix[i][j] = ++counter; } } } else if (rows < columns) { int counter = (int) Math.pow(Math.min(rows, columns), 2); int sqrt = (int) Math.sqrt(counter); for (int i = sqrt; i < columns; i++) { for (int j = 0; j < rows; j++) { matrix[j][i] = ++counter; } } } } private static void print() { for (int[] row : matrix) { for (int i : row) { System.out.printf("%4d ", i); } System.out.println(); } }}