Java-面试复习-整理03

本文详细介绍了各种排序算法,包括冒泡、选择、插入、Shell、快速、归并和堆排序,分析了它们的时间复杂度和稳定性。同时,阐述了分治策略在算法设计中的应用,如二分查找和归并排序。此外,还探讨了动态规划的基本要素,以解决具有最优子结构和子问题重叠的问题,并通过实例展示了动态规划的求解过程。
摘要由CSDN通过智能技术生成

一些算法

排序算法

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值