一篇文章搞定Java稀疏数组!

简介: 一篇文章搞定Java稀疏数组!

数组有很多形式,可以用来做很多事情,像是最简单的储存数据,还可以储存二叉树,储存图……

什么是稀疏数组?

其实这个和储存图的一种形式差不多。

首先来看一下稀疏数组的应用场景:
假如要写一个五子棋小程序,用1来表示白子,用2表示蓝子,用0来表示空。


显然我们要定义一个二维数组来储存这些数据,那么这样需要用大量的内存,空间复杂度太大,要遍历时,浪费的空间复杂度是O(n^2),那么我们要优化这么一个程序,显然要缩小空间复杂度,那么我们就需要用到稀疏数组。

下面我们引入稀疏数组数组的介绍:

当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。 稀疏数组的处理方法是:

  1. 记录数组一共有几行几列,有多少个不同的值
  2. 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模

下面我们引入一个实例:

在这里,我们第一行第一列记录这个数组一共有多少行,第一行第二列记录有多少列,第三列记录有多少个有效元素。

从第二行开始,第一列记录第一个有效元素的行标,第二列记录列表,第三列记录这个元素的值。

1)从二维数组转化为稀疏数组

首先我们要遍历整个数组,得到非0元素的个数,也就得到了第一行第三列的元素。 其次,创建对应的稀疏数组

然后,遍历二维数组,将二维数组中非零元素存到sparesArr中

2)把稀疏数组转化为二维数组

先读取稀疏数组的第一行元素,根据其数据,创建原始的二维数组

然后读取稀疏数组的后几行元素(从第二行开始),并赋值给二维数组即可
这个数据结构算是比较简单的,我在leetcode上面也没有找到相关的练习题。

下面我们来介绍它的代码实现:

package Java.sparsearray;
public class SparseArray {
  public static void main(String[] args) {
    //创建一个原始的二维数组
    //0:没有棋子,1:黑子,2:蓝子
    int chessArr1[][] = new int[11][11];
    //下面先固定二维数组的元素,后面可优化~
    chessArr1[1][2] = 1;
    chessArr1[2][3] = 2;
    chessArr1[4][5] = 2;
    //输出原始的二维数组:
    System.out.println("原始的二维数组:");
    for(int[] row:chessArr1) {
      for(int data:row) {
        System.out.printf("%d ",data);
      }
      System.out.println();
    }
    //下面将二维数组转化为稀疏数组
    //1.先遍历二维数组,得到非0数据的个数
    int sum = 0;
    for(int i=0;i<11;i++) {
      for(int j=0;j<11;j++) {
        if(chessArr1[i][j] != 0) {
          sum++;
        }
      }
    }
    //2.创建对应的稀疏数组
    int sparesArr[][] = new int[sum+1][3];
    //给稀疏数组赋值
    sparesArr[0][0] = 11;
    sparesArr[0][1] = 11;
    sparesArr[0][2] = sum;
    //遍历二维数组,将非0的值存放在sparesArr中
    int count = 0;//count 用于记录是第几个非0数据
    for(int i = 0;i<11;i++) {
      for(int j=0;j<11;j++) {
        if(chessArr1[i][j] != 0) {
          count++;
          sparesArr[count][0] = i;
          sparesArr[count][1] = j;
          sparesArr[count][2] = chessArr1[i][j];
        }
      }
    }
    //输出稀疏数组的形式
    System.out.println();
    System.out.println("得到的稀疏数组为:");
    for(int i=0;i<sparesArr.length;i++) {
      System.out.printf("%d\t%d\t%d\t\n",sparesArr[i][0],sparesArr[i][1],sparesArr[i][2]);
    }
    System.out.println();
    //下面将稀疏数组恢复成二维数组
    //先读取稀疏数组的第一行元素,根据其数据,创建原始的二维数组
    int chessArr2[][] = new int[sparesArr[0][0]][sparesArr[0][1]];;
    //读取稀疏数组后几行的元素(从第二行开始),并赋值给原始的二维数组即可
    for(int i=1;i<sparesArr.length;i++) {
      chessArr2[sparesArr[i][0]][sparesArr[i][1]] = sparesArr[i][2];
    }
    //输出恢复后的二维数组
    System.out.println();
    System.out.println("恢复后的二维数组");
    for(int[] row:chessArr2) {
      for(int data:row) {
        System.out.printf("%d\t",data);
      }
      System.out.println();
    }
  }
}
相关文章
|
2月前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第17天】本文详细介绍了Java编程中Map的使用,涵盖Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的并发处理和性能优化技巧,适合初学者和进阶者学习。
58 3
|
2月前
|
存储 缓存 算法
Java 数组
【10月更文挑战第19天】Java 数组是一种非常实用的数据结构,它为我们提供了一种简单而有效的方式来存储和管理数据。通过合理地使用数组,我们能够提高程序的运行效率和代码的可读性。更加深入地了解和掌握 Java 数组的特性和应用,为我们的编程之旅增添更多的精彩。
33 4
|
2月前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第19天】本文介绍了Java编程中重要的数据结构——Map,通过问答形式讲解了Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的使用和性能优化技巧,适合初学者和进阶者学习。
73 4
|
2月前
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
36 2
|
2月前
|
存储 Java
Java“(array) <X> Not Initialized” (数组未初始化)错误解决
在Java中,遇到“(array) &lt;X&gt; Not Initialized”(数组未初始化)错误时,表示数组变量已被声明但尚未初始化。解决方法是在使用数组之前,通过指定数组的大小和类型来初始化数组,例如:`int[] arr = new int[5];` 或 `String[] strArr = new String[10];`。
91 2
|
2月前
|
存储 Java
什么是带有示例的 Java 中的交错数组?
什么是带有示例的 Java 中的交错数组?
53 9
|
2月前
|
Java
Java数组动态扩容和动态缩减
Java数组动态扩容和动态缩减
25 3
|
2月前
|
存储 算法 Java
Java一分钟之-数组的创建与遍历
数组作为Java中存储和操作一组相同类型数据的基本结构,其创建和遍历是编程基础中的基础。通过不同的创建方式,可以根据实际需求灵活地初始化数组。而选择合适的遍历方法,则可以提高代码的可读性和效率。掌握这些基本技能,对于深入学习Java乃至其他编程语言的数据结构和算法都是至关重要的。
30 6
|
2月前
|
存储 Java 程序员
【一步一步了解Java系列】:何为数组,何为引用类型
【一步一步了解Java系列】:何为数组,何为引用类型
31 1
|
2月前
|
存储 XML Java
如何在 Java 中将常见文档转换为 PNG 图像数组
如何在 Java 中将常见文档转换为 PNG 图像数组
17 1