稀疏數組

  • 2021 年 12 月 17 日
  • 筆記

在遇到棋盤或者地圖等問題時,常常需要構造一個二維數組。以棋盤為例,需要大量的0(或者其他相同的默認數值)來組成棋盤的基本結構,而數組中非0值的位置卻很少。為了節省空間,可以用稀疏數組來存儲相應資訊。

稀疏數組是一個3列的二維數組,稀疏數組的第一行總是存儲原來二維數組的行列和有效值的資訊。分別是:

  1. 第一行第一列存原來二維數組的總行數
  2. 第一行第二列存原來二維數組的總列數
  3. 第一行第三列存原來二維數組的非0(有效)值的總個數

從稀疏數組的第二行往下,存放原來二維數組的有效資訊,每一個有效值的資訊在稀疏數組中的存放形式如下:

  1. 第1列存放某一個有效值出現的行
  2. 第2列存放那一個有效值出現的列
  3. 第3列存放那個有效的值

原來一個9*9的大數組,在使用稀疏數組後,變成一個5*3的小數組,節約了空間。圖上能反應出稀疏數組與原來二維數組的對應關係。

  • 二維數組–>稀疏數組

通過遍歷原來的二維數組可以找到每一個有效值的資訊,然後賦值給稀疏數組。

java程式碼實現:

 1  public static int[][] twoToSparse(int[][] arr) {
 2         //將二維數組變成稀疏數組
 3         int sum = 0; //記錄原數組有幾個非0的值,用於確定稀疏數組的行數
 4         int columnNum = 0; //記錄原數組的列數
 5         for (int[] ints : arr) {
 6             columnNum = ints.length; //獲取列數
 7             for (int anInt : ints) {
 8                 if (anInt != 0) {
 9                     sum++;
10                 }
11             }
12         }
13         int[][] sparseArr = new int[sum + 1][3];
14         sparseArr[0][0] = arr.length;
15         sparseArr[0][1] = columnNum;
16         sparseArr[0][2] = sum;
17         int count = 0;//紀錄出現的值是第幾個
18         for (int i = 0; i < arr.length; i++) {  //遍歷原來的二維數組,找到非0處的值,將資訊賦值給稀疏數組
19             for (int j = 0; j < columnNum; j++) {
20                 if (arr[i][j] != 0) {
21                     count++; //第幾個出現就放在第幾行(第0行存放原數組的 總行數,總列數,總非0的值的數量)
22                     sparseArr[count][0] = i; //第一列存放行數
23                     sparseArr[count][1] = j; //第二列存放列數
24                     sparseArr[count][2] = arr[i][j]; //第三列存放具體的值
25                 }
26             }
27         }
28         return sparseArr;
29     }
  • 稀疏數組–>二維數組

通過遍歷稀疏數組的資訊,很快就能獲得二維數組的資訊,然後將原來需要的二維數組恢復。

java程式碼實現:

 1     public static int[][] sparseToTwo(int[][] sparseArr) {
 2         //將稀疏數組恢復成二維數組
 3         int[][] arr = new int[sparseArr[0][0]][sparseArr[0][1]]; //利用稀疏數組中第一行的總行列數資訊,創建一個二維數組
 4         if (sparseArr[0][2] == 0) {
 5             return arr; //沒有有效值,直接返回只有默認值的數組,這裡默認值是0,不需要進行另外的賦值操作
 6         } else {
 7             for (int i = 1; i < sparseArr.length; i++) {
 8                 arr[sparseArr[i][0]][sparseArr[i][1]]=sparseArr[i][2];  //遍歷稀疏數組,讀取行,列,值資訊,賦給二維數組
 9 
10             }
11             return arr;
12         }
13     }