《Java小子怒闯数据结构九重天》第一重天——数组

简介: 自古以来数据结构界就分为九重天,据说冲破这九重天之后就可以去进攻算法界最终修炼最后成佬,受万人敬仰,以下内容先讲述第一重内容。

前言


自古以来数据结构界就分为九重天,据说冲破这九重天之后就可以去进攻算法界最终修炼最后成佬,受万人敬仰。


但是这谈何容易,因为每一重天都有神兽把守,想要冲破每一重天都必须收服守护的神兽才行。


守护九重天的神兽分别是:数组、字符串、栈、队列、链表、树、散列表、堆、图。可见他们的战斗力也是逐层增强的。想只凭靠自身的能力拿下他们谈何容易。


不过大家不必惊慌,我这里有一本上古秘籍《Java小子怒闯数据结构九重天》,里面有每一重天神兽的攻略。只要修炼者仔细钻研里面的每一篇,对九重天了如指掌之后,冲破这九重天也是易如反掌的。


今天为大家带来第一重天的攻略!

image.png

1.🌀数组基础知识


数组:数组是可以在内存中连续存储多个相同类型的数据元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进行访问,数组下标从0开始。


1.1 数组中需要注意的点:


数组的本质是什么呢?数组就是一片地址连续且空间大小一致的存储空间(但是每个空间存的还是其他数据的地址)


为什么空间大小是相等的呢?就是为了方便统一维护我们的数据,必须得保证数据之间的类型是一样的。(多个同类型的变量空间连在一起组成的结构叫数组)

数组存在于堆内存中,但凡在堆中存储的数据都称之为对象,但凡在堆内存中创建的对象都会有默认初始值


(1)整数类型数组默认值均为0

(2)浮点类型数组默认值均为0.0

(3)布尔类型数组默认值均为false


数组变量存的就是数组在堆内存中首元素的地址


数组一旦定义下来,其长度不可改变;


创建数组时必须明确规定大小或内容


二维数组我们也称之为矩阵,即:数组中的每一个元素为一个矩阵。如矩阵a:a[3][3]={{1,2,2}{5,5,9}{8,9,7}}


2.🌀初始化数组

一般来说Java初始化数组为以下格式,声明数组的同时开辟数组空间。


数组类型[] 数组名 = new 数据类型[数组长度];


这里的两个类型都是相同的只不过叫法不一样而已,要注意的是类型可以是8种基本的数据类型,也可以是引用数据类型。


这里的引用类型也可以是自已创建类型,假如你创建了一个关于图书的Book类,那么你也可以为Book类创建一个数组,如:


Book[] books = new Book[3];


这里就是创建了三本书的一个数组。


除了以上方式创建数组之外我们还会把声明数组与开辟空间分开来进行初始化数组。如下:

//声明数组变量
String[] arr;
int arr1[];
//数组对象实例化长度为3(开辟数组空间)
arr1 = new int[3];
arr = new String[3];


或者我们在创建数组的时候直接给数组进行赋值。这样的话并不会直接声明数组的长度。如下:


int[] array2 = new  int[]{1, 2, 3, 4, 5};

int[] array3 = {1, 2, 3, 4, 5};


3.🌀数组常用API

API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。


在Java中有许多关于数组的API,这些API也会简化一些我们涉及到数组的操作。


而想要收服数组,那么这些API你一定也要熟记于心。


首先关于数组的方法都在java.util.Arrays;这个包下,我们在使用之前也是需要先导入这个包才行。如下:


import java.util.Arrays;


常用数组的一些api或用法如下:


3.1 使用length方法求数组长度


int len = array.length;


3.2 使用for循环遍历打印数组


//方法一:使用普通for循环遍历数组

for(int i = 0; i < array.length; i ++) {

    System.out.println(array[i]);

}

//方法二:使用增强for循环遍历数组

for(int num : array) {

    System.out.println(num);

}



3.3 使用toString()方法将int类型数组转成字符串string类型数组


String arrStrings = Arrays.toString(array);

1

3.4 使用fill()方法填充数组


//将数组array全部用10填充

Arrays.fill(array, 10);  


3.5 使用sort()方法对数组从小到大进行排序;


//方法1:sort(int[] a)   放入数组名字

Arrays.sort(array);

//方法2:sort(a, fromIndex, toIndex)  从第几个到第几个之间的进行排序

Arrays.sort(array, 1 , 4);


3.6 使用copyof()方法复制数组

//方法 1
int[] arr6 = {3, 7, 2, 1};
//指定新数组的长度
int[] arr7 = Arrays.copyOf(arr6, 10);  
//方法 2
//只复制从索引[1]到索引[3]之间的元素(不包括索引[3]的元素)     
int[] arr8 = Arrays.copyOfRange(arr6, 1, 3);


3.7 使用asList()方法将数组转成List集合类型


String[] array = {"1", "2", "3"};

List list = Arrays.asList(array);


3.8 将数组转成set集合


String[] array = new String[]{"1", "2", "3"};

Set set = new HashSet(Arrays.asList(array));


4.🌀数组进阶练习

Leetcode 217. 存在重复元素

微信图片_20220523223606.png

解法一:排序法

最容易想到的就是排序了,先对数组元素进行排序,在排序之后相同的元素就会相邻了,我们在遍历数组如果相邻的元素相等,那么说明存在重复元素了。


代码实现:

class Solution {
    public boolean containsDuplicate(int[] nums) {
        Arrays.sort(nums);
        for(int i = 1; i < nums.length; i ++) {
            if(nums[i] == nums[i - 1]) {
                return true;
            }
        }
        return false;
    }
}


输出结果:

image.png

通过了但是时间复杂度太高。


解法二:利用哈希表的去重特性

创建一个哈希表,然后从左往右遍历数组将数组中的元素加入哈希表。检测哈希表中是否已存在当前字符,若存在,直接返回结果,若不存在,将当前字符加入哈希表,供后续判断使用即可。


代码实现:

class Solution {
    public boolean containsDuplicate(int[] nums) {
        Set set = new HashSet();
        for(int i : nums) {
            if(!set.add(i)) {
                return true;
            }
        }
        return false;
    }
}


输出结果:

image.png

可以看到我们算法的效率提高了不少。


我们仅仅是使用了其他的数据结构,就帮助我们提高了算法效率。


虽然我们没有学习哈希表相关特性,但是我们从这个解法二上面看到其他数据结构的魅力。这就够了我们后面会学习的。


结语

恭喜你修炼到这里,你已经基本有了收服神兽数组的能力。神兽数组是我们到进攻算法界最重要的能力之一。大家不可懈怠。



相关文章
|
1月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
69 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
23天前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
38 1
|
25天前
|
存储 Java
告别混乱!用Java Map优雅管理你的数据结构
【10月更文挑战第17天】在软件开发中,随着项目复杂度增加,数据结构的组织和管理至关重要。Java中的Map接口提供了一种优雅的解决方案,帮助我们高效、清晰地管理数据。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,有效提升了代码质量和维护性。
80 2
|
25天前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
57 2
|
8天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
29 6
|
14天前
|
存储 Java 索引
Java中的数据结构:ArrayList和LinkedList的比较
【10月更文挑战第28天】在Java编程世界中,数据结构是构建复杂程序的基石。本文将深入探讨两种常用的数据结构:ArrayList和LinkedList,通过直观的比喻和实例分析,揭示它们各自的优势与局限,帮助你在面对不同的编程挑战时做出明智的选择。
|
1月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
30 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
22天前
|
存储 算法 Java
Java 中常用的数据结构
【10月更文挑战第20天】这些数据结构在 Java 编程中都有着广泛的应用,掌握它们的特点和用法对于提高编程能力和解决实际问题非常重要。
24 6
|
23天前
|
存储 缓存 算法
Java 数组
【10月更文挑战第19天】Java 数组是一种非常实用的数据结构,它为我们提供了一种简单而有效的方式来存储和管理数据。通过合理地使用数组,我们能够提高程序的运行效率和代码的可读性。更加深入地了解和掌握 Java 数组的特性和应用,为我们的编程之旅增添更多的精彩。
31 4
|
23天前
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
19 2