稀疏数组
概念:
某些场景下,二维数组保存的值大多数为0,只有少量不为0的值。这种情况下,没有意义的值(为0的数据)较多,我们可以将它压缩为较小的数组,保存其中有意义的值即可。
常见的场景就是保存围棋、五子棋等的残局。网上说明挺多,可自行查找。
数据结构与算法 栏目是本人自学时做的相关笔记与总结,有兴趣的可以关注查看。
示例
原始素组:
0 1 0 0
0 0 0 0
0 0 2 0
0 0 0 0
0 0 0 0
可以看见多数值为0,大小为5行*4列。
转为稀疏数组为:
row col val
5 4 2 ==>第一行分别记录原始数组有几行(5行),几列(4列),几个不为0的值(2个)
0 1 1 ==>第二行记录第一个不为0的值的位置和它的值,这个值是在原始数组的第1行(下标从0开始)、第2列,值为1
2 2 2 ==>第三行记录第二个不为0的值的位置和它的值,这个值是在原始数组的第3行(下标从0开始)、第3列,值为2
此时大小为:3行*3列,压缩了一半。
原始数组转稀疏数组思路:
1.遍历原始数组获取有几个不为0的值(创建稀疏数组时需要)
2.创建稀疏数组
2.遍历原始数组,将不为0的值赋值到稀疏数组
稀疏数组转原始数组思路:
1.根据稀疏数组保存的原始数组大小创建原始数组
2.遍历原始数组,将值赋值到原始数组
代码
原始数组转稀疏数组
public int[][] originArrTransformToSparseArr(int[][] origin) {
int count = 0;
//第一步 遍历原始数组获取有几个不为0的值
for (int i = 0; i < origin.length; i++) {
for (int j = 0; j < origin[0].length; j++) {
if (origin[i][j] > 0) {
count++;
}
}
}
//第二步 创建稀疏数组,注意:因为稀疏数组第一行记录了原始数组信息,第二行开始记录不同值的信息
// 所以行数是比count大一的,为 count + 1,列是固定的3列
int[][] resultArr = new int[count + 1][3];
resultArr[0][0] = origin.length;
resultArr[0][1] = origin[0].length;
resultArr[0][2] = count;
//记录数据应该插到第几行
int line = 0;
//第三步 遍历原始数组,保存不为0的值的信息
for (int i = 0; i < origin.length; i++) {
for (int j = 0; j < origin[0].length; j++) {
if (origin[i][j] > 0) {
line++;
// 值所在的行
resultArr[line][0] = i;
//值所在的列
resultArr[line][1] = j;
//值的大小
resultArr[line][2] = origin[i][j];
}
}
}
return resultArr;
}
稀疏数组转原始数组
public int[][] sparseArrTransformToOriginArr(int[][] origin) {
//第一不创建原始数组
int[][] resultArr = new int[origin[0][0]][origin[0][1]];
//遍历稀疏数组给原始数组赋值
//注意:i是从1开始,因为稀疏数组第一行记录的不是不为0的值的信息
for (int i = 1; i < origin.length; i++) {
resultArr[origin[i][0]][origin[i][1]] = origin[i][2];
}
return resultArr;
}