jjzjj

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

abcccccccccccccccode 2023-04-10 原文

本专栏文章主要用于帮助Java使用者快速上手数据结构,刷算法题!

前言

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

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

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

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

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

目录

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);

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<String> list = Arrays.asList(array);

3.8 将数组转成set集合

String[] array = new String[]{"1", "2", "3"};
Set<Integer> set = new HashSet(Arrays.asList(array));

4.🌀数组进阶练习

Leetcode 217. 存在重复元素

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

代码实现:

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;
    }
}

输出结果:

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

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

代码实现:

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

输出结果:

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

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

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


算法对程序员来说及其重要,语言和开发平台不断变化,但是万变不离其宗的是那些算法和理论,刷算法最最最直白的原因就是找一个好的工作,那刷题一定是必不可少的就是一个好的刷题平台。现在算法刷题平台鱼龙混杂,非常多。如何选择一个正确的刷题平台呢?

这里我推荐牛客网如果你对相应语言的基础语法已经比较自信了那你也可以刷算法题,这里牛客网对算法题的难度分类也是很棒的,有入门题,面试必刷题,面试高频题等等。如果基础比较差那么也不用担心,牛客网上面也有基础语法题来帮助你更好地学习基础。

为了大家方便刷题我直接把牛客网的链接放在下面,大家点击蓝色字体就可以直接进行跳转刷题了!

传送门:刷题入口

刷题这件事,大家一定要认真起来,不可懈怠!

结语

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

感兴趣的修炼者可以关注下面公众号,会持续推送最新更新的!

持续更新中…

有关《Java小子怒闯数据结构九重天》第一重天——数组的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  5. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  6. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  7. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  8. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  9. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  10. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

随机推荐