这是一个简单的任务,以“之字形”移动求和矩阵中的元素 按水平。变量“ sumPath”必须很长,会抛出“ java.lang.OutOfMemoryError”。
我有两个“ for”周期,需要缩短它们。
我该怎么做?
代码如下:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.next());
int m = Integer.parseInt(scanner.next());
int[][] matrix = new int[n][m];
long sumPath = 1;
matrix[0][0] = 1;
for (int row = 0; row < n; row++) {
if (row > 0) {
matrix[row][0] = matrix[row - 1][0] + 3;
}
for (int col = 1; col < m; col++) {
matrix[row][col] = matrix[row][col - 1] + 3;
}
}
int row = 0;
while (row < n-1) {
for (int col = 1; col < m; col++) {
if (col % 2 == 0) {
sumPath = sumPath + matrix[row][col];
} else {
sumPath = sumPath + matrix[row+1][col];
}
}
row = row + 2;
if (row >= n) {
break;
}
for (int col = m - 2; col >= 0; col--) {
if (col % 2 == 0) {
sumPath = sumPath + matrix[row][col];
} else {
sumPath = sumPath + matrix[row-1][col];
}
}
}
System.out.println(sumPath);
}
}
答案 0 :(得分:0)
只有一行代码可能会发生OutOfMemoryException:
int[][] matrix = new int[n][m];
矩阵必须完全适合内存。当数字n和m太大时,矩阵对于可用内存将变得太大。
答案 1 :(得分:0)
肯定地,初始化数组时您拥有OutOfMemoryError
int[][] matrix = new int[n][m]
对于大n
和m
来说,这是很烦人的(例如,默认设置为JVM
,您肯定会得到n = m = 100_000
的例外)。
但是请注意,您不必创建整个数组。计算路径时,仅使用有限数量的矩阵像元,并且仅在需要时才可以计算。
private static final int ZERO = 1;
private static final int OFFS = 3;
public static int get(int row, int col) {
int val = ZERO;
for (int i = 0; i < row; i++)
val += OFFS;
for (int i = 0; i < col; i++)
val += OFFS;
return val;
}
是的,创建矩阵会比较慢,但是绝对可以保护您免受OutOfMemoryError
的侵害。为了提高速度,您可以缓存计算的值:
private static final Map<Integer, Map<Integer, Integer>> MAP = new HashMap<>();
public static int get(int row, int col) {
Map<Integer, Integer> values = MAP.computeIfAbsent(row, k -> new HashMap<>());
if (!values.containsKey(col)) {
int val = ZERO;
for (int i = 0; i < row; i++)
val += OFFS;
for (int i = 0; i < col; i++)
val += OFFS;
values.put(col, val);
}
return values.get(col);
}
PS 这是您的解决方案的外观:
public static void main(String... args) {
try (Scanner scan = new Scanner(System.in)) {
System.out.print("Height: ");
int height = scan.nextInt();
System.out.print("Width: ");
int width = scan.nextInt();
System.out.println(calcSumPath(height, width));
}
}
private static long calcSumPath(int height, int width) {
long sumPath = ZERO;
int row = 0;
while (row < height - 1) {
for (int col = 1; col < width; col++)
sumPath += get(col % 2 == 0 ? row : row + 1, col);
row += 2;
if (row >= height)
break;
for (int col = width - 2; col >= 0; col--)
sumPath += get(col % 2 == 0 ? row : row - 1, col);
}
return sumPath;
}
private static final int ZERO = 1;
private static final int OFFS = 3;
private static final Map<Integer, Map<Integer, Integer>> MAP = new HashMap<>();
public static int get(int row, int col) {
Map<Integer, Integer> values = MAP.computeIfAbsent(row, k -> new HashMap<>());
if (!values.containsKey(col)) {
int val = ZERO;
for (int i = 0; i < row; i++)
val += OFFS;
for (int i = 0; i < col; i++)
val += OFFS;
values.put(col, val);
}
return values.get(col);
}