《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

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


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


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


结语

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



相关文章
|
14天前
|
存储 Java 索引
Java快速入门之数组、方法
### Java快速入门之数组与方法简介 #### 一、数组 数组是一种容器,用于存储同种数据类型的多个值。定义数组时需指定数据类型,如`int[]`只能存储整数。数组的初始化分为静态和动态两种: - **静态初始化**:直接指定元素,系统自动计算长度,如`int[] arr = {1, 2, 3};` - **动态初始化**:手动指定长度,系统给定默认值,如`int[] arr = new int[3];` 数组访问通过索引完成,索引从0开始,最大索引为`数组.length - 1`。遍历数组常用`for`循环。常见操作包括求和、找最值、统计特定条件元素等。
|
4月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
115 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
4月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
59 1
|
4月前
|
存储 Java
告别混乱!用Java Map优雅管理你的数据结构
【10月更文挑战第17天】在软件开发中,随着项目复杂度增加,数据结构的组织和管理至关重要。Java中的Map接口提供了一种优雅的解决方案,帮助我们高效、清晰地管理数据。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,有效提升了代码质量和维护性。
108 2
|
4月前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
109 2
|
14天前
|
存储 Java 索引
Java基础(六):数组
Java基础(六):数组
Java基础(六):数组
|
13天前
|
存储 Java C++
Java数组:静态初始化与动态初始化详解
本文介绍了Java中数组的定义、特点及初始化方式。
44 12
|
2月前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
51 5
|
3月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
92 5
|
3月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
77 4