假设给定一个整数的上三角矩阵,最佳的Java存储方式是什么?朴素的二维int数组显然不够高效。我想到的解决方案已经移动到答案部分了。
1 2 6 3 7 8 4 1 9 5
我建议根据总和公式(n² + n) / 2
(行和列从零开始)简化计算索引。list_index = (column^2 + column) / 2 + row;
public class TriangularMatrix {
private final int[] list;
public TriangularMatrix(int size) {
list = new int[sumFormula(size)];
}
public int set(int row, int column, int value) {
validateArguments(row, column);
int listIndex = getListIndex(row, column);
int oldValue = list[listIndex];
list[listIndex] = value;
return oldValue;
}
public int get(int row, int column) {
validateArguments(row, column);
return list[getListIndex(row, column)];
}
private void validateArguments(int row, int column) {
if (row > column) {
throw new IllegalArgumentException("Row (" + row + " given) has to be smaller or equal than column (" + column + " given)!");
}
}
private int getListIndex(int row, int column) {
return sumFormula(column) + row;
}
private int sumFormula(int i) {
return (i*i + i) / 2;
}
}
这里有另一个关于SO讨论性能影响的问题,尽管它是关于Fortran。
如果矩阵始终为对角矩阵,我会使用:
List<List<Integer>> matrix = ...
Map<Map<Integer>> = ...
我认为我找到了解决方案。这是我的解决方案:假设您有一个4X4的上三角矩阵M。
1 2 3 4
0 6 7 1
0 0 8 9
0 0 0 5
如果你能将M中的每个元素映射到一个一维数组中,那将是最好的解决方案。你需要知道的就是哪个矩阵的[row,col]对应于你的一维数组中的哪个元素。以下是实现方法:
start_index=((col_index-1)+1)+((col_index-2)+1)+...+1
end_index=start_index + col_index
start_index=((3-1)+1)+((3-2)+1)+((3-3)+1)=6
end_index=6+3=9
所以,我只需要从数组的第6个索引开始,读取所有元素直到第9个索引(包括第9个元素)。按照这个步骤,你就可以在(n + n^2)/2的空间中存储和检索nXn矩阵的所有单元格。