用于快速复习:算法

本文深入探讨了递归的概念,通过反转链表的例子进行说明。接着,解释了动态规划的原理,用斐波那契数列展示其如何利用缓存优化计算。此外,还介绍了贪心算法的应用,如硬币找零问题。最后,简要阐述了插入排序和归并排序这两种排序算法的工作原理。
摘要由CSDN通过智能技术生成

1.算法为体

1.1 各路算法体

递归是什么,递归就是吃,假如是10,就不断递归吃到结束,然后再往上走
也就是先递归到边界条件,然后再回溯

https://blog.csdn.net/m0_37907797/article/details/102767860?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164404809216780265416190%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164404809216780265416190&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-102767860.pc_search_result_control_group&utm_term=%E9%80%92%E5%BD%92&spm=1018.2226.3001.4187

在这里面可以得到递归算法的三个步骤

  • 这个函数的功能是什么
  • 边界条件:什么时候递归结束
  • 执行代码
  • 递归:开始递归

心法

递归就是一生二,二生三,三生万物,万物归一
问题可以拆分递归为子问题,子问题的解又返回,在写代码前可以先想象出图形才写代码(如归并,如肥波纳妾)

1.1帮助快速复习的题目

递归就是吃往回吃,吃到最后再回溯
反转打印链表

    public void showReversed(MyNode head){
        if(head==null|| head.next==null){ // 吃,吃到最后结束条件
            return ;
        }
        showReversed(head.next);   // 吃够了开始回溯操作
        System.out.println(head.next.data);
    }

1.2 动态规划

我的理解,动态规划就是一种优化,下一个子问题的解是基于上一个子问题的解,将返回值存储起来(类似缓存一样),在又一次计算该变量的时候,可以先查看缓存中时候有该返回值时,有,直接取,无,计算再存储。
如:

 // 肥波纳妾
 public static int[] memory = new int[20];
    public final static double loaderFactor = 0.75;

    public static int fib(int n){
        
        if(n==1 || n==2){
            return 1;
        }
        // 缓存中有
        if(memory[n]!=0){
            return memory[n];
        }
        // 如果不存在
        int result = fib(n-1)+fib(n-2);
        // 存储缓存
        if(n>memory.length){

        }
        return 1;
    }

    private void resize(){
        int newLength = memory.length>>1;
        int []temp = new int[newLength];
        for(int i=0;i<memory.length;i++){
            temp[i] = memory[i];
        }
        memory = temp;
    }

背包问题
重点:
表格为二维数组,f [ i ][ j ] ,存储子问题的解,表示前i个物品中,在当前j重量的背包中的最大价值。
在这里插入图片描述
先看视频理解步骤再看代码
重要步骤步骤:
if :当前物品的重量w[i] 是否能加入当前容量j的背包
yes:当前物品的价值val[ i ] +f[i-1][j-w[i]](剩余的重量所能加入的最大价值)是否大于f[i-1][j]
yes:加入f[i][j]
No:加入上一个子问题的解

		int[] w = {1, 4, 3};//物品的重量
        int[] val = {1500, 3000, 2000}; //物品的价值 这里val[i] 就是前面讲的v[i]
        int m = 4; //背包的容量
        int n = val.length; //物品的个数
        int[][] v = new int[n + 1][m + 1];   // 前i个物品,当前容量

        // 初始化
        // 当只有0个容量时
        for (int i = 0; i < n + 1; i++) {
            v[i][0] = 0;
        }
        // 当前只有0个物品
        for (int i = 0; i < m + 1; i++) {
            v[0][i] = 0;
        }

        for (int i = 1; i < n + 1; i++) {
            for (int j = 1; j < m + 1; j++) {
                // 当前物品是否小于当前背包的容量
                if (w[i-1] > j) {
                    // 如果大于
                    // 获取子问题的解
                    v[i][j] = v[i - 1][j];
                } else {
                    // 如果小于
                    // 判断当前价值加上剩余容量价值是否大于子问题的价值
                    if ((val[i - 1] + v[i - 1][j - w[i - 1]]) > v[i - 1][j]) {
                        // 如果大于
                        v[i][j] = val[i - 1] + v[i - 1][j - w[i - 1]];

                    }else{
                        v[i][j] = v[i-1][j];
                    }
                }
            }
        }
        System.out.println(v[n][m]);

1.3 贪心算法

求解问题的时候,永远选择最优解,获取问题的最优解
子问题 ----》 当前最优解 —》子问题—》当前最优解

贪心算法场景:
可以拆解子问题,子问题的解需要选择最优解
提出贪心策略
如硬币找零,找最大面值

2.排序

2.1 插入算法

快速复习法:代码搭配动图看。
插入就是,一个有序列[0,i),[i,++]一个无序列,insertIndex=i-1,如果insertValue(nums[i]),小于nums[insertIndex],那么当前的数就往后面移一位,nums[insertIndex+1] = nums[insertIndex]。如果大于nums[insertIndex]的话,就插入到insertIndex+1.

    public static void insertSort(int[] arr) {
        int insertVal = false;
        int insertIndex = false;

        for(int i = 1; i < arr.length; ++i) {
            int insertVal = arr[i];

            int insertIndex;
            for(insertIndex = i - 1; insertIndex >= 0 && insertVal < arr[insertIndex]; --insertIndex) {
                arr[insertIndex + 1] = arr[insertIndex];
            }

            if (insertIndex + 1 != i) {
                arr[insertIndex + 1] = insertVal;
            }
        }

    }
}

2.2 归并排序

public static void sort(int nums[],int left,int right){
        if(left<right){  //边界条件
            int mid = (left + right)/2;
            sort(nums,left,mid); // 左递归
            sort(nums,mid+1,right);// 右递归
            merge(nums,left,right);// merge

        }
    }
    public static void merge(int []nums,int left,int right){
        int mid = (left + right)/2;
        int i = left; // 左边开始索引
        int j = mid + 1; // 右边开始索引
        while(i<=mid && j<=right){
            if(nums[i]<nums[j]){
                i++;
            }else{   // 如果右边小于左边
                int temp = nums[i];
                nums[i] = nums[j];
                nums[j] = temp;
                j++;
                i++;
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值