Java-面试复习-整理03

tech2026-04-10  2

目录

一些算法排序算法分治动态规划

一些算法

排序算法

1.冒泡:1.时间复杂度:平均O(n2),最好O(n),最坏O(n2)    空间复杂度:O(1)    稳定(没有发生跳跃式的交换:排序前后相同数字的前后顺序没有改变)    每次将最大的数放到后面

public static int[] bubbleSort(int[] arr) { if(arr == null || arr.length <= 1){ return arr; } for(int i=0;i<arr.length-1;i++){ int a=0; for(int j=0;j<arr.length-1-i;j++){//每次循环结束后最后一个元素为当前最大元素 if(arr[j]>arr[j+1]){//将大数往后移 int tmp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=tmp; a++; } } if(a==0){//所有数有序 break; } } return arr; }

2.选择:时间复杂度:O(n2),平均、最好、最坏都是    空间复杂度:O(1)    不稳定    从待排序数字的后面找到比当前待排序数字小的数字进行交换(每次将最小的放到前面)

3.直接插入:时间复杂度:平均O(n2),最好O(n),最坏O(n2),越有序越快    空间复杂度:O(1)    稳定    每次将在前面的比当前数大的放在后面,当前数从1开始,放在tmp,从前面找大的放在当前位置,一直往前,不大则跳出,将tmp放到前面的停止位置。

4.Shell:时间复杂度:平均O(n1.3),最好O(n),最坏O(n2)    空间复杂度:0(1)    不稳定    组内进行有序(插入排序),每次除了数组,传入一个gap,作为分组的间隔, 进行多次,直到gap为1,则全部有序

5.快排:时间复杂度:平均0(nlog2n),最好0(nlog2n),最坏O(n2)    空间复杂度:0(log2n)    不稳定    每次获得一个基准数,将前面的大数放到它后面,后面的小数放到它前面,直到low和high相遇,得到基准数的位置,再对后面和前面进行重复操作,直到每块都只有一个数,则全部有序。    基准默认选取分区中的第一个数,优化可以在分区中随机选择,或在low、high和中间三个数中取中间大小的数    快排的本质就是把比基准数大的放在基准数的右边,比基准数小的放在基准数的左边,这样就找到了该数据在数组中的正确位置。然后递归的对前半部分和后半部分继续排序。    有序时时间复杂度最坏,每次得到的基准都在最前面或最后面,一次只能得到一个有序数,划分的剩下的区间为n-1

6.归并:时间复杂度:平均0(nlog2n),最好0(nlog2n),最坏0(nlog2n)    空间复杂度:0(n)    稳定    使每个子序列有序,再使子序列段间有序    归并应用了分治法的思想,将已有序的子序列合并,得到完全有序的序列,即先使每个子序列有序,再使子序列段间有序。    归并操作的工作原理如下:    第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后序列    第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置    第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置    重复步骤3直到某一指针超出序列尾    将另一序列剩下的所有元素直接复制到合并序列尾

7.堆排:时间复杂度:平均0(nlog2n),最好0(nlog2n),最坏0(nlog2n)    空间复杂度:0(1)    不稳定    建立大根堆,每次将最大的放在后面

分治

   分治算法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题性质相同,求出子问题的解,就可以得到原问题的解。    步骤:1.分解;2.求解;3.合并    例如:二分查找、归并排序。

动态规划

   能用动归算法解决的问题,都有两个基本的要素:    1.最优子结构    2.子问题划分有重叠

   动态规划解决问题,主要找出两样东西:    1.“状态” dp[i] :如组成价值i所需要的最少的硬币的数量    2.状态转移方程

public static int maxW(int money,int n,int[] p,int[] w){ int maxw = 0; int[][] dp = new int[n+1][money+1]; for(int i = 1;i<n+1;i++){ for(int j = 1;j<money+1;j++){ if(p[i]>j){ dp[i][j] = dp[i-1][j]; }else { dp[i][j] = Math.max(dp[i-1][j],dp[i][j-p[i]]+w[i]);//此为0-多背包,若为0-1,则后面为dp[i-1][j-p[i]]+w[i] } } } maxw = dp[n][money]; return maxw; }
最新回复(0)