JAVA 算法面试总结

1、二分查找

二分查找又叫折半查找,要求待查找的序列有序。每次取中间位置的值与待查关键字比较,如果中间位置
的值比待查关键字大,则在前半部分循环这个查找的过程,如果中间位置的值比待查关键字小,
则在后半部分循环这个查找的过程。直到查找到了为止,否则序列中没有待查的关键字。
示例:

public static int biSearch(int []array,int a){int lo=0;int hi=array.length-1;int mid;while(lo<=hi){mid=(lo+hi)/2;//中间位置if(array[mid]==a){return mid+1;}else if(array[mid]<a){ //向右查找lo=mid+1;}else{ //向左查找hi=mid-1;}}return -1;}

2、冒泡排序算法

(1)比较前后相邻的二个数据,如果前面数据大于后面的数据,就将这二个数据交换。
(2)这样对数组的第 0 个数据到 N-1 个数据进行一次遍历后,最大的一个数据就“沉”到数组第
N-1 个位置。

(3)N=N-1,如果 N 不为 0 就重复前面二步,否则排序完成。

public static void bubbleSort1(int[] a, int n) {int i, j;for (i = 0; i < n; i++) {//表示 n 次排序过程for (j = 1; j < n - i; j++) {if (a[j - 1] > a[j]) {//前面的数字大于后面的数字就交换//交换 a[j-1]和 a[j]int temp;temp = a[j - 1];a[j - 1] = a[j];a[j] = temp;}}}}

3、插入排序算法

通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。
插入排序非常类似于整扑克牌。在开始摸牌时,左手是空的,牌面朝下放在桌上。接着,一次从
桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,要将
它与手中已有的牌从右到左地进行比较。无论什么时候,左手中的牌都是排好序的。
如果输入数组已经是排好序的话,插入排序出现最佳情况,其运行时间是输入规模的一个线性函
数。如果输入数组是逆序排列的,将出现最坏情况。平均情况与最坏情况一样,其时间代价是(n2)。
在这里插入图片描述

public void sort(int arr[]){for (int i = 1; i < arr.length; i++) {//插入的数int insertVal = arr[i];//被插入的位置(准备和前一个数比较)int index = i - 1;//如果插入的数比被插入的数小while (index >= 0 && insertVal < arr[index]) {//将把 arr[index] 向后移动arr[index + 1] = arr[index];//让 index 向前移动index--;}//把插入的数放入合适位置arr[index + 1] = insertVal;}}

4、快速排序算法

快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),
比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。
一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有
继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比
较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的
值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值
来说,左右两边就是有序的了

public void sort(int[] a, int low, int high) {int start = low;int end = high;int key = a[low];while (end > start) {//从后往前比较while (end > start && a[end] >= key)//如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较end--;if (a[end] <= key) {int temp = a[end];a[end] = a[start];a[start] = temp;}//从前往后比较while (end > start && a[start] <= key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置start++;if (a[start] >= key) {int temp = a[start];a[start] = a[end];a[end] = temp;}//此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用}//递归if (start > low) sort(a, low, start - 1);//左边序列。第一个索引位置到关键值索引-1if (end < high) sort(a, end + 1, high);//右边序列。从关键值索引+1 到最后一个}

在这里插入图片描述

5、希尔排序算法

基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列
中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

  1. 操作方法:
    选择一个增量序列 t1,t2,…,tk,其中 ti>tj,tk=1;
  2. 按增量序列个数 k,对序列进行 k 趟排序;
  3. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进
    行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长
    度。
    在这里插入图片描述
private void shellSort(int[] a) {int dk = a.length / 2;while (dk >= 1) {ShellInsertSort(a, dk);dk = dk / 2;}}private void ShellInsertSort(int[] a, int dk) {
//类似插入排序,只是插入排序增量是 1,这里增量是 dk,把 1 换成 dk 就可以了for (int i = dk; i < a.length; i++) {if (a[i] < a[i - dk]) {int j;int x = a[i];//x 为待插入元素a[i] = a[i - dk];for (j = i - dk; j >= 0 && x < a[j]; j = j - dk) {
//通过循环,逐个后移一位找到要插入的位置。a[j + dk] = a[j];}a[j + dk] = x;//插入}}}

6、归并排序算法

归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列
分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
在这里插入图片描述

public static void main(String[] args) {int[] data = new int[]{5, 3, 6, 2, 1, 9, 4, 8, 7};print(data);mergeSort(data);System.out.println("排序后的数组:");print(data);}public static void mergeSort(int[] data) {sort(data, 0, data.length - 1);}public static void sort(int[] data, int left, int right) {if (left >= right)return;// 找出中间索引int center = (left + right) / 2;// 对左边数组进行递归sort(data, left, center);// 对右边数组进行递归sort(data, center + 1, right);// 合并merge(data, left, center, right);print(data);}/*** 将两个数组进行归并,归并前面 2 个数组已有序,归并后依然有序* Page 239 of 283** @param data   数组对象* @param left   左数组的第一个元素的索引* @param center 左数组的最后一个元素的索引,center+1 是右数组第一个元素的索引* @param right  右数组最后一个元素的索引*/public static void merge(int[] data, int left, int center, int right) {// 临时数组int[] tmpArr = new int[data.length];// 右数组第一个元素索引int mid = center + 1;// third 记录临时数组的索引int third = left;// 缓存左数组第一个元素的索引int tmp = left;while (left <= center && mid <= right) {// 从两个数组中取出最小的放入临时数组if (data[left] <= data[mid]) {tmpArr[third++] = data[left++];} else {tmpArr[third++] = data[mid++];}}// 剩余部分依次放入临时数组(实际上两个 while 只会执行其中一个)while (mid <= right) {tmpArr[third++] = data[mid++];}while (left <= center) {tmpArr[third++] = data[left++];}// 将临时数组中的内容拷贝回原数组中// (原 left-right 范围的内容被复制回原数组)while (tmp <= right) {data[tmp] = tmpArr[tmp++];}}public static void print(int[] data) {for (int i = 0; i < data.length; i++) {System.out.print(data[i] + "\t");}System.out.println();}

7、桶排序算法

桶排序的基本思想是: 把数组 arr 划分为 n 个大小相同子区间(桶),每个子区间各自排序,最
后合并 。计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况。
1.找出待排序数组中的最大值 max、最小值 min
2.我们使用 动态数组 ArrayList 作为桶,桶里放的元素也用 ArrayList 存储。桶的数量为(maxmin)/arr.length+1
3.遍历数组 arr,计算每个元素 arr[i] 放的桶
4.每个桶各自排序

public static void bucketSort(int[] arr) {int max = Integer.MIN_VALUE;int min = Integer.MAX_VALUE;for (int i = 0; i < arr.length; i++) {max = Math.max(max, arr[i]);min = Math.min(min, arr[i]);}//创建桶int bucketNum = (max - min) / arr.length + 1;ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);for (int i = 0; i < bucketNum; i++) {bucketArr.add(new ArrayList<Integer>());}//将每个元素放入桶for (int i = 0; i < arr.length; i++) {int num = (arr[i] - min) / (arr.length);bucketArr.get(num).add(arr[i]);}for (int i = 0; i < bucketArr.size(); i++) {Collections.sort(bucketArr.get(i));}}

8、基数排序算法

将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位
开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

public class radixSort {int a[] = {49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 101, 56, 17, 18, 23, 34, 15, 35, 25, 53, 51};public radixSort() {sort(a);for (int i = 0; i < a.length; i++) {System.out.println(a[i]);}}public void sort(int[] array) {//首先确定排序的趟数;int max = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > max) {max = array[i];}}int time = 0;//判断位数;while (max > 0) {max /= 10;time++;}//建立 10 个队列;List<ArrayList> queue = new ArrayList<ArrayList>();for (int i = 0; i < 10; i++) {ArrayList<Integer> queue1 = new ArrayList<Integer>();queue.add(queue1);}//进行 time 次分配和收集;for (int i = 0; i < time; i++) {//分配数组元素;for (int j = 0; j < array.length; j++) {//得到数字的第 time+1 位数;int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);ArrayList<Integer> queue2 = queue.get(x);queue2.add(array[j]);queue.set(x, queue2);}int count = 0;//元素计数器;//收集队列元素;for (int k = 0; k < 10; k++) {while (queue.get(k).size() > 0) {ArrayList<Integer> queue3 = queue.get(k);array[count] = queue3.get(0);queue3.remove(0);count++;}}}}}

9、剪枝算法

在搜索算法中优化中,剪枝,就是通过某种判断,避免一些不必要的遍历过程,形象的说,就是
剪去了搜索树中的某些“枝条”,故称剪枝。应用剪枝优化的核心问题是设计剪枝判断方法,即
确定哪些枝条应当舍弃,哪些枝条应当保留的方法
在这里插入图片描述

10、回溯算法

回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现
已不满足求解条件时,就“回溯”返回,尝试别的路径。

11、最短路径算法

从某顶点出发,沿图的边到达另一顶点所经过的路径中,各边上权值之和最小的一条路径叫做最
短路径。解决最短路的问题有以下算法,Dijkstra 算法,Bellman-Ford 算法,Floyd 算法和 SPFA
算法等。

12、最小生成树算法

现在假设有一个很实际的问题:我们要在 n 个城市中建立一个通信网络,则连通这 n 个城市需要
布置 n-1 一条通信线路,这个时候我们需要考虑如何在成本最低的情况下建立这个通信网?
于是我们就可以引入连通图来解决我们遇到的问题,n 个城市就是图上的 n 个顶点,然后,边表示
两个城市的通信线路,每条边上的权重就是我们搭建这条线路所需要的成本,所以现在我们有 n 个
顶点的连通网可以建立不同的生成树,每一颗生成树都可以作为一个通信网,当我们构造这个连
通网所花的成本最小时,搭建该连通网的生成树,就称为最小生成树。

构造最小生成树有很多算法,但是他们都是利用了最小生成树的同一种性质:MST 性质(假设
N=(V,{E})是一个连通网,U 是顶点集 V 的一个非空子集,如果(u,v)是一条具有最小权值的边,
其中 u 属于 U,v 属于 V-U,则必定存在一颗包含边(u,v)的最小生成树),下面就介绍两种使
用 MST 性质生成最小生成树的算法:普里姆算法和克鲁斯卡尔算法。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/185935.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ONE·Linux || 网络基础(四)】

总言 主要内容&#xff1a;传输层UDP、TCP协议基本介绍。UDP报文格式、TCP报文格式、三次握手四次挥手、TCP可靠性策略说明。 文章目录 总言8、UDP协议&#xff08;传输层一&#xff09;8.1、传输层预备知识8.1.1、端口号8.1.2、一些指令&#xff08;netstat、pidof、xargs&am…

热烈欢迎省工信厅毛郑建处长莅临公司调研指导工作

2023年11月28日&#xff0c;河南省工信厅信息化和软件服务业处毛郑建处长莅临郑州埃文计算机科技有限公司&#xff08;以下简称“埃文科技”&#xff09;调研考察工作。河南省工业信息安全产业发展联盟理事长任传军陪同调研。 首先&#xff0c;埃文科技董事长王永向毛处长介绍埃…

优维全新低碳产品亮相SBE23 Asia-Pacific绿色建筑促进碳中和论坛

2023年11月23日—24日&#xff0c;由深圳市人民政府主办&#xff0c;深圳市住房和建设局、深圳市发展与改革委员会、深圳市龙岗区人民政府承办&#xff0c;深圳市绿色建筑协会作为执行单位的“2023年可持续建筑环境亚太地区会议&#xff08;SBE23 Asia-Pacific&#xff09;”在…

Ubuntu Server 20.04.6安装Anaconda3

下载安装包 去下面的网页找到自己想要安装的对应版本的链接&#xff1a; https://repo.anaconda.com/archive/ 我安装的版本链接如下&#xff1a; https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.sh 复制这个链接后使用如下命令下载&#xff1a; wget …

一篇文章带你掌握MongoDB

文章目录 1. 前言2. MongoDB简介3. MongoDB与关系型数据库的对比4. MongoDB的安装5. Compass的使用6. MongoDB的常用语句7. 总结 1. 前言 本文旨在帮助大家快速了解MongoDB,快速了解和掌握MongoDB的干货内容. 2. MongoDB简介 MongoDB是一种NoSQL数据库&#xff0c;采用了文档…

arthas使用

官方文档 Github: https://github.com/alibaba/arthas 文档: https://arthas.aliyun.com/doc/ Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断…

C语言从入门到实战——常用字符函数和字符串函数的了解和模拟实现

常用字符函数和字符串函数的了解和模拟实现 前言1. 字符分类函数2. 字符转换函数3. strlen的使用和模拟实现4. strcpy的使用和模拟实现5. strcat的使用和模拟实现6. strcmp的使用和模拟实现7. strncpy函数的使用8. strncat函数的使用9. strncmp函数的使用10. strstr的使用和模拟…

MatchPyramid实现文本匹配

引言 今天利用MatchPyramid实现文本匹配。 原论文解析→点此←。 MatchPyramid 核心思想是计算两段文本间的匹配矩阵&#xff0c;把它当成一个图形利用多层卷积网络提取不同层级的交互模式。 匹配矩阵是通过计算两段输入文本基本单元(比如字或词)之间相似度得到的&#xf…

43.0BaseDao抽取dao公共父类

43.1. 回顾 1. 把数据库表中查询的结果封装到一个实体类中。 命名规则:类名和表名一致 类中属性和表的字段对应。 表中的一条记录对应实体的一个对象 多条记录→集合 43.2. 正文 目录 43.1. 回顾 43.2. 正文 43.3. 抽取dao公共父类。 43.4. 引入数据源 43.3. 抽取dao公共…

C#测试开源运行耗时库MethodTimer.Fody

微信公众号“dotNET跨平台”的文章《一个监控C#方法运行耗时开源库》介绍了支持测量方法耗时的包MethodTimer.Fody&#xff0c;使用方便&#xff0c;还可以自定义输出信息格式。本文学习并测试MethodTimer.Fody包的使用方式。   新建控制台程序&#xff0c;通过Nuget包管理器…

Python链式调用技巧:代码流畅无缝连接

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 链式调用是一种编程风格&#xff0c;它允许将多个方法调用连接在一起&#xff0c;形成一个连贯的操作链。在Python中&#xff0c;链式调用常常用于使代码更简洁、易读&#xff0c;尤其在处理数据处理和函数式编程…

web:ics-05(本地文件包含漏洞、preg_replace函数/e漏洞、php伪协议读取文件)

题目 打开页面显示如下 只有这个页面能打开 显示如下 用dirsearch扫一下 查看了一下&#xff0c;发现没什么用 查看页面源代码 返回了&#xff0c;写入的参数&#xff0c;猜测可能有文件包含漏洞 用php伪协议读取文件 构造payload ?pagephp://filter/readconvert.base64-en…

WordPress定时文章自动发布技巧

对于许多WordPress站长来说&#xff0c;文章的管理和发布计划往往是一个头疼的问题。随着内容的不断增加&#xff0c;时间表的调整以及发布频率的把握成为了让人焦头烂额的挑战。 一、时间管理难题 对于博客管理员来说&#xff0c;时间管理一直是个令人困扰的问题。在忙碌的生…

Springboot-注册注解【springboot常用注解】

1.组件注册 1.1 使用的注解 Configuration:普通配置类,替代以前的配置文件,配置类本身也是容器的组件|SpringBootConfiguration:Springboot配置类,与Configuration功能一样|Bean:替代以前的Bean标签,如果没有在Bean标签内定义名字,则默认组件的名字为方法名,可以直接修改注解…

简单0成本构建一个企业内部的视频点播、培训直播、安防监控、录像管理于一体的数字视频管理体系

以前&#xff0c;企业要构建一套数字化的视频管理体系&#xff0c;把企业内部的各种视频文件、直播培训、安防监控视频都整合到一套流媒体音视频服务里面&#xff0c;实现统一的对外供货、对外赋能的方案&#xff0c;是很困难的&#xff01;因为&#xff0c;原来这都是好几个项…

【Web】NewStarCTF Week4 个人复现

目录 ①逃 ②More Fast ③midsql ④InjectMe ⑤PharOne ⑥flask disk ①逃 一眼字符串逃逸 bad 替换为 good 字符增加一位 先构造一下试试 <?php class GetFlag {public $key;public $cmd "ls /";} $a new GetFlag(); echo serialize($a); 得到O:7:…

windows配置服务开机自启和保活

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、下载WinSW&#xff1f;二、使用步骤1.解压2.配置3.安装服务4.服务启停5.服务卸载6.开机自启7.保活 总结 前言 写了一个程序或者是exe&#xff0c;或者是ba…

Jmeter接口测试:jmeter_HTTP Cookie管理器看这一篇文章就够了

HTTP Cookie管理器 HTTP Cookie管理器可以像浏览器一样自动存储和发送cookie&#xff0c;以这种自 动收集的方式收集到的cookie不会在cookie manager中进行展示&#xff0c;但是运行后&#xff0c; 可以通过 查看结果树&#xff08;监听器&#xff09;可以查看到cookie信息 除…

java单例模式

文章目录 单例模式3、懒汉式 - 懒汉式非线程安全4、饿汉式 - 线程安全5、懒汉式和饿汉式区别6、双重检查锁定7、应用场景 来讲讲java单例 单例模式 java中单例模式是一种常见的设计模式&#xff0c;单例模式的写法有好几种&#xff0c;这里主要介绍三种&#xff1a;懒汉式单例…

抑制过拟合——Dropout原理

抑制过拟合——Dropout原理 Dropout的工作原理 实验观察 在机器学习领域&#xff0c;尤其是当我们处理复杂的模型和有限的训练样本时&#xff0c;一个常见的问题是过拟合。简而言之&#xff0c;过拟合发生在模型对训练数据学得太好&#xff0c;以至于它捕捉到了数据中的噪声和…