一篇文章搞定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();
    }
  }
}
相关文章
|
存储 缓存 Java
Java数组全解析:一维、多维与内存模型
本文深入解析Java数组的内存布局与操作技巧,涵盖一维及多维数组的声明、初始化、内存模型,以及数组常见陷阱和性能优化。通过图文结合的方式帮助开发者彻底理解数组本质,并提供Arrays工具类的实用方法与面试高频问题解析,助你掌握数组核心知识,避免常见错误。
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第17天】本文详细介绍了Java编程中Map的使用,涵盖Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的并发处理和性能优化技巧,适合初学者和进阶者学习。
914 3
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
存储 Java 索引
Java快速入门之数组、方法
### Java快速入门之数组与方法简介 #### 一、数组 数组是一种容器,用于存储同种数据类型的多个值。定义数组时需指定数据类型,如`int[]`只能存储整数。数组的初始化分为静态和动态两种: - **静态初始化**:直接指定元素,系统自动计算长度,如`int[] arr = {1, 2, 3};` - **动态初始化**:手动指定长度,系统给定默认值,如`int[] arr = new int[3];` 数组访问通过索引完成,索引从0开始,最大索引为`数组.length - 1`。遍历数组常用`for`循环。常见操作包括求和、找最值、统计特定条件元素等。
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
657 157
|
存储 Java 索引
java 数组
在 Java 中,数组是一种数据结构,用于存储多个相同类型的数据元素。数组的大小一旦创建后就不能改变,因此它是固定长度的。Java 数组是一种 对象,即使它存储的值是基本类型(如 int、double 等),它也是一个对象引用。
332 0
|
人工智能 Java
Java 中数组Array和列表List的转换
本文介绍了数组与列表之间的相互转换方法,主要包括三部分:1)使用`Collections.addAll()`方法将数组转为列表,适用于引用类型,效率较高;2)通过`new ArrayList&lt;&gt;()`构造器结合`Arrays.asList()`实现类似功能;3)利用JDK8的`Stream`流式计算,支持基本数据类型数组的转换。此外,还详细讲解了列表转数组的方法,如借助`Stream`实现不同类型数组间的转换,并附带代码示例与执行结果,帮助读者深入理解两种数据结构的互转技巧。
1198 1
Java 中数组Array和列表List的转换
|
存储 监控 Java
《从头开始学java,一天一个知识点》之:数组入门:一维数组的定义与遍历
**你是否也经历过这些崩溃瞬间?** - 看了三天教程,连`i++`和`++i`的区别都说不清 - 面试时被追问&quot;`a==b`和`equals()`的区别&quot;,大脑突然空白 - 写出的代码总是莫名报NPE,却不知道问题出在哪个运算符 这个系列就是为你打造的Java「速效救心丸」!我们承诺:每天1分钟,地铁通勤、午休间隙即可完成学习;直击痛点,只讲高频考点和实际开发中的「坑位」;拒绝臃肿,没有冗长概念堆砌,每篇都有可运行的代码标本。明日预告:《多维数组与常见操作》。 通过实例讲解数组的核心认知、趣味场景应用、企业级开发规范及优化技巧,帮助你快速掌握Java数组的精髓。
719 23