3 回答
TA贡献1966条经验 获得超4个赞
根据您在我的第一个答案下的评论:
我也在考虑另一种解决方案......使用 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,1
1,1
1,0
-----
0,2
1,2
2,2
2,1
2,0
-----
0,3
1,3
2,3
3,3
3,2
3,1
3,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 调用上述方法4x5
public 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, *, *]
这篇文章比我实际想象的要长。但我希望它很容易理解。
TA贡献1815条经验 获得超13个赞
如果您查看 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();
}
}
}
TA贡献1862条经验 获得超7个赞
如果你沿着左栏看,就会发现一个模式:
1
4
9
16
其中 是(r + 1)^2,其中r是行号。
沿行,值递减 1,直到对角线,其中r == c:
1
4 3
9 8 7
16 15 14 13
这是(r + 1)^2 - c.
如果你沿着顶行看,就会发现一个模式:
1 2 5 10
这是c^2 + 1.
沿着列行向下,值增加 1,直到对角线,其中r == c:
1 2 5 10
3 6 11
7 12
13
这是c^2 + 1 + r
因此,您可以使用嵌套循环计算数组元素:
for (int r = 0; r < N; ++r) {
for (int c = 0; c < M; ++c) {
matrix[r][c] = (r >= c) ? ((r + 1)*(r + 1) - c) : (c * c + 1 + r);
}
}
添加回答
举报