当前位置: 首页 > 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…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...