当前位置: 首页 > news >正文

Java数据结构和算法相关面试题


天行健,君子以自强不息;地势坤,君子以厚德载物。


每个人都有惰性,但不断学习是好好生活的根本,共勉!


文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。


《送别》
寻阳五溪水,沿洄直入巫山里。胜境由来人共传,
君到南中自称美。送君别有八月秋,飒飒芦花复益愁。
云帆望远不相见,日暮长江空自流。


文章目录

  • 数据结构和算法
    • 1. 时间复杂度和空间复杂度
      • 1.1 时间复杂度
      • 1.2 空间复杂度
    • 2. 数组和链表的结构对比
      • 2.1 数组
        • 概念
        • 数组的特性
      • 2.2 链表
        • 概念
        • 链表的特性
        • 常见的链表
        • 应用
    • 3. 遍历一个树
    • 4. 冒泡排序 Bubble Sort
      • 4.1 算法描述
      • 4.2 复杂度
      • 4.3 代码实现
    • 5. 快速排序 Quick Sort
      • 5.1 算法描述
      • 5.2 复杂度
      • 5.3 代码实现
    • 6. 二分查找 Binary Search
      • 6.1 算法描述
      • 6.2 复杂度
      • 6.3 代码实现
      • 6.4 拓展


数据结构和算法

1. 时间复杂度和空间复杂度

时间复杂度和空间复杂度是衡量一个算法是否高效的重要标准
时间复杂度不是算法执行的时间,这是错误的

1.1 时间复杂度

指的是算法语句执行的次数,如O(1), O(n), O(logn), O(n2)

1.2 空间复杂度

指的是一个算法在运行过程中临时占用的存储空间大小,即被创建次数最多的变量被创建了多少次,这个算法的空间复杂度就是多少
如果算法语句中就有创建对象,那么该算法的时间复杂度和空间复杂度一般一致
算法语句被执行了多少次就创建了多少个对象

2. 数组和链表的结构对比

2.1 数组

概念

相同数据类型的元素按一定顺序排列的集合
就是把有限个类型相同的变量用一个名字,改名字就是数组名,用编号区分数组中变量,编号就是下标

数组的特性
  • 数组必须先定义固定长度,不能动态适应数据动态增减
  • 当数据增加时,可能超出原先定义的元素个数,当数据减少时,造成内存浪费
  • 数据查询比较方便,根据下标就可以直接找到元素,时间复杂度O(1),增加和删除比较复杂,需要移动操作数所在位置后的所有数据,时间复杂度为O(N)

2.2 链表

概念

一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的

链表的特性
  • 链表动态进行存储分配,可适应数据动态增减
  • 插入、删除数据比较方便,时间复杂度为O(1),查询必须从头开始找起,时间复杂度为O(N),相当麻烦
常见的链表
  • 单链表,链表每一个元素都要保存一个指向下一个元素的指针
  • 双链表,每个元素既要保存到下一个元素的指针,还要保存一个上一个元素的指针
  • 循环链表,在最后一个元素中下一个元素指针指向首元素

链表和数组都是在堆里分配内存

应用

快速访问数据,较少或不插入和删除元素时,用数组更好
较多插入和删除元素时,使用链表数据结构更高效

3. 遍历一个树

四个遍历概念

  • 先序遍历,先访问根节点,再访问左子树,最后访问右子树
  • 后序遍历,先左子树,再右子树,最后根节点
  • 中序遍历,先左子树,再根节点,最后右子树
  • 层序遍历,每一层从左到右访问每一个节点

每一个子树遍历时依然按照此时的遍历顺序,可以采用递归实现遍历

4. 冒泡排序 Bubble Sort

4.1 算法描述

  • 比较相邻的元素,第一个比第二个大,则交换两个元素位置
  • 对每一个相邻元素作同样的工作,从开始第一对到结尾的最后一对,在最后的元素应该会是最大的数
  • 对所有元素重复以上操作,除了最后一个元素
  • 重复前面三个步骤,直到排序完成

4.2 复杂度

排序方法时间复杂度(平均)时间复杂度(最坏)时间复杂度(最好)空间复杂度稳定性
冒泡排序O(n2),2在n的右上角标O(n2),2在n的右上角标O(n)O(1)稳定

如果两个元素相等,不会再交换位置,所以冒泡排序是一种稳定排序算法

4.3 代码实现

冒泡排序

public class BubbleSort{public static void bubbleSort(int[] arr){for(int i = 0; i< arr.length-1; i++){for(int j = 0; j< arr.length-i-1; j++){if(arr[j] > arr[j+1]){//当前面的值大于后面的值,交换位置int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}}public static void main(String[] args){int[] arr = {4,2,5,1,9,3};bubbleSort(arr);for(int i : arr){System.out.print(i+"");}}
}

5. 快速排序 Quick Sort

5.1 算法描述

使用分治法将一串list分为两个子串sub-list,具体如下

  • 从数列中挑出一个元素,称为基准pivot
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任意一边)。在这个分区退出后,该基准数处于数列的中间位置,这个称为分区操作partition
  • 递归地rcursive将小于基准值元素的子数列和大于基准值元素的子数列排序

5.2 复杂度

排序方法时间复杂度(平均)时间复杂度(最坏)时间复杂度(最好)空间复杂度稳定性
快速排序O(nlog2n),2在log右下角标O(n2), 2在n的右上角标O(nlog2n), 2在log右下角标O(nlog2n), 2在log右下角标稳定

key值的选取可以有多种形式,例如中间数或随机数,分别会对算法的复杂度产生不同的影响

5.3 代码实现

快速排序

public class QuickSort{public static void quickSort(int[] data, int low, int high){int i,j,temp,t;if(low>high){return;}i = low;j = high;//temp为基准位temp = data[low];System.out.println("基准位:"+temp);while(i<j){//先看右边,依次往左递减while(temp<=data[j]&&i<j){j--;}//再看左边,依次往右递增while(temp>=data[i]&&i<j){i++;}//如果满足条件则交换if(i<j){System.out.println("交换: "+data[i]+" 和 "+data[j]);t = data[j];data[j] = data[i];data[i] = t;System.out.println(java.util.Arrays.toString(data))}}//最后将基准位与i和j相等位置的数字互换System.out.println("基准位 "+temp+" 和i、j相遇的位置 "+data[i]+"交换");data[low] = data[i];data[i] = temp;System.out.println(java.util.Arrays.toString(data));//递归调用左半数组quickSort(data, low, j-1);//递归调用右半数组quickSort(data, j+1, high);}public static void main(String[] args){int[] data = {3, 44, 34, 5, 25, 58, 20, 1, 57, 23, 12, 60, 43};System.out.println("排序之前:\n"+java.util.Arrays.toString(data));quickSort(data, 0, data.length-1);System.out.println("排序之后:\n"+java.util.Arrays.toString(data));}}

6. 二分查找 Binary Search

6.1 算法描述

  • 二分查找又称为折半查找,是一种效率较高的查找方法,要求列表中的元素是有序排列的,即如果未排序则必须先排序才可进行二分查找
  • 假定表中元素按升序排序,将表中中间位置记录的关键字与查找的关键字进行比较,如果两者相等则查找成功
  • 如果不相等,利用中间位置记录将表分成前后两个子表,如果中间位置记录的关键字大于所要查找的关键字,则进行查找前一个子表,否则就去查后一个子表
  • 重复以上过程,知道找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功

6.2 复杂度

二分查找法
时间复杂度为O(log2n)
空间复杂度为O(1)

6.3 代码实现

二分法查找

public class BinarySearch{public static int binarySearch(int[] arr, int left, int right, int findValue){if(left>right){//递归推出条件, 找不到,返回-1return -1}int midIndex = (left+right)/2;if(finaValue<arr[midIndex]>){//向左递归查找return binarySearch(arr, left, midIndex, findValue);}else if(findValue>arr[midIndex]){//向右递归查找return binarySearch(arr, midIndex, right, findValue);}else{return midIndex;}}public static void main(String[] args){//注意:需要对已排序的数组进行二分查找int[] data = {-40, -30, -12, -1, 2, 33, 38, 49, 50};int i = binarySearch(data, 0, data.length, 33);System.out.println(i);}
}

6.4 拓展

当有序数组中有多个相同的数值时,如何将所有的数值都查到

代码

public class BinarySearch2{public static List<Integer> binarySearch2(int[] arr, int left, int right, int findValue){List<Integer> list = new ArrayList<>();if(left>right){//递归退出条件,找不到,返回-1return list;}int midIndex = (left+right)/2;int midValue = arr[midIndex];if(findValue<midValue){//向左递归查找return binarySearch2(arr, left, mdiIndex-1, findValue);}else if(findValue>midValue){//向右递归查找return binarySearch2(arr, midIndex+1, right, findValue);}else{System.out.println("midIndex="+midIndex);//向左扫描int temp = midIndex-1;while(true){if(temp<0||arr[temp]!=findValue){break;}if(arr[temp]==findValue){list.add(temp);}temp -= 1;}//将中间这个索引加入list.add(midIndex);//向右边扫描temp = midIndex + 1;while(true){if(temp>arr.length-1||arr[temp]!=findValue){break;}if(arr[temp]==findValue){list.add(temp);}temp += 1;}return list;}}public static void main(String[] args){//注意: 需要对已排序的数组进行二分查找int[] data = {1, 4, 10, 58, 100, 1000, 1200, 1234, 1234, 3000, 4000};List<Integer> list = binarySearch2(data, 0, data.length, 1234);System.out.println(list);}
}

感谢阅读,祝君暴富!


相关文章:

Java数据结构和算法相关面试题

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

网络安全风险评估

项目背景 随着信息化技术的快速发展&#xff0c;特别是面向社会、政府机构、企业等业务系统的投入使用&#xff0c;各组织机构对网络和信息系统安全防护都提出了新的要求。为满足安全需求&#xff0c;需对组织机构的网络和信息系统的安全进行一次系统全面的评估&#xff0c;以…...

ADAM优化算法与学习率调度器:深度学习中的关键工具

深度学习模型的训练效果离不开优化算法和学习率的选择。ADAM&#xff08;Adaptive Moment Estimation&#xff09;作为深度学习领域中广泛应用的优化算法之一&#xff0c;以其高效性和鲁棒性成为许多任务的默认选择。而学习率调度器则是优化算法的“助推器”&#xff0c;帮助训…...

岛屿数量C++11新特性

每日一题 200. 岛屿数量 class Solution {//使用深度的优先搜索来搜索岛屿图//遍历整个图片 当char数组的值为1时开始从这个点开始往外扩散搜索//注意处理边界 图不是正方形 public:int ans;int d[4][2] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};int N;int M;void dfs(vector<…...

Git 快速入门:全面了解与安装步骤

Git 快速入门&#xff1a;全面了解与安装步骤 一、关于Git 1.1 简介 Git 是一个开源的分布式版本控制系统&#xff0c;由 Linus Torvalds 于 2005 年创建&#xff0c;最初是为了更好地管理 Linux 内核开发而设计。 Git用于跟踪计算机文件的变化&#xff0c;特别是源代码文件…...

基于域自适应的双光融合

目录 引言DAF-Net编码器-解码器分支编码器部分融合层解码器部分 域自适应层概述多核最大均值差异&#xff08;MK-MMD&#xff09;第一阶段&#xff1a;编码器-解码器分支训练训练过程损失函数 第二阶段&#xff1a;融合层训练训练过程损失函数 实验与结果总结 文章声明&#xf…...

迭代器模式 (Iterator Pattern)

文章目录 迭代器模式 (Iterator Pattern)原理优点缺点示例代码场景描述1. 定义迭代器接口2. 定义集合接口3. 实现具体集合类4. 客户端代码输出结果 UML 类图使用场景优化与扩展小结 迭代器模式 (Iterator Pattern) 迭代器模式是一种 行为型设计模式&#xff0c;用于顺序访问集…...

039集——渐变色之:CAD中画彩虹()(CAD—C#二次开发入门)

&#xff08;来左边儿 跟我一起画个龙&#xff0c;在你右边儿 画一道彩虹 ~~~~~~~~~~~ &#xff09; 效果如下&#xff1a; namespace AcTools {public class Class1{public Wform.Timer timer;//定时器需建在类下面public static DateTime startTime;[CommandM…...

如何将 GitHub 私有仓库(private)转换为公共仓库(public)

文章目录 如何将 GitHub 私有仓库转换为公共仓库步骤 1: 登录 GitHub步骤 2: 导航到目标仓库步骤 3: 访问仓库设置步骤 4: 更改仓库可见性步骤 5: 确认更改步骤 6: 验证更改注意事项 如何将 GitHub 私有仓库转换为公共仓库 在软件开发领域&#xff0c;GitHub 是一个广受欢迎的…...

C++11 右值引用

目录 左值 右值 左值引用与右值引用比较 左值引用总结&#xff1a; 右值引用总结&#xff1a; 左值引用的使用场景&#xff1a; 引用传参和做返回值都可以提高效率(减少拷贝) 左值引用的短板&#xff1a; 右值引用和移动语义解决上述问题&#xff1a; 下面就是有移动…...

WPS表格学习计划与策略

一、学习目标 掌握WPS表格的基本操作:包括新建、打开、保存工作簿,单元格的编辑与格式化,数据的输入与验证等。熟练运用WPS表格的数据处理功能:包括数据排序、筛选、分类汇总,以及使用公式和函数进行计算和分析。学会制作图表与数据可视化:掌握不同类型图表(如柱状图、折…...

Android 引入 proto 项目及使用方法

Proto&#xff08;Protocol Buffers&#xff09;是Google开发的一种语言无关、平台无关的序列化结构数据的方法&#xff0c;它类似于JSON和XML&#xff0c;但相对于XML而言更小&#xff0c;相对于JSON而言解析更快&#xff0c;支持多语言。以下是将Proto引入Android项目的方法及…...

VSOMEIP主要流程的时序

请求服务: client应用&#xff1a; ​ application_impl::request_service ​ routing_manager_client::request_service (老版本是routing_manager_proxy) ​ routing_manager_client::send_request_services ​ protocol::request_service_command its_command; // 创建…...

右值引用和移动语义:

C 右值引用和移动语义详解 在 C 的发展历程中&#xff0c;右值引用和移动语义的引入带来了显著的性能提升和编程灵活性。本文将深入探讨右值引用和移动语义的概念、用法以及重要性。 一、引言 C 作为一门高效的编程语言&#xff0c;一直在不断演进以满足现代软件编程的需求。…...

经纬高LLA转地心地固ECEF坐标,公式,代码

经纬高转地心地固的目的 坐标系转换是gis或者slam系统常见操作。GNSS获取的一般是经纬高&#xff0c;经纬高在slam系统里无法应用&#xff0c;slam系统一般是xyz互相垂直的笛卡尔坐标系&#xff0c;所以需要把GNSS的经纬高转到直角坐标系地心地固ECEF或者高斯投影GKP。 划重点…...

VUE前端实现天爱滑块验证码--详细教程

第一步&#xff1a; Git地址&#xff1a;tianai-captcha-demo: 滑块验证码demo 找到目录 src/main/resources/static,拷贝 static 并改名为 tac 即可。 第二步&#xff1a; 将改为 tac 的文件&#xff0c;放进项目根目录中&#xff0c;如下图&#xff1a; 第三步&#xff1…...

【链表】【删除节点】【刷题笔记】【灵神题单】

237.删除链表的节点 链表删除节点的本质是不用删除&#xff0c;只需要操作指针&#xff0c;跳过需要删除的节点&#xff0c;指向下下一个节点即可&#xff01; 删除某个节点&#xff0c;但是不知道这个节点的前一个节点&#xff0c;也不知道头节点&#xff01;摘自力扣评论区…...

springboot339javaweb的新能源充电系统pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;新能源充电系统的设计与实现 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解…...

【嵌入式——QT】QT制作安装包

第一步 QT程序写好之后&#xff0c;编译release版本 第二步 拿到release生成的.exe文件 第三步 新建文件夹deploy 第四步 将.exe文件复制到deploy目录下 第五步 在该目录下输入cmd指令&#xff0c;回车 第六步 在打开的命令窗口下输入 windeployqt TegNetCom_1.0.…...

python的文件操作练习

文件操作&#xff1a;成绩统计 有一个文件grades.txt&#xff0c;文件内容是每行一个学生的成绩&#xff08;格式&#xff1a;姓名,成绩&#xff09;。要求&#xff1a; 读取文件内容&#xff0c;统计所有学生的平均成绩&#xff1b; 将不及格&#xff08;<60分&#xff09…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...