数据结构与算法学习(第九天)(动态规划,串)

动态规划(Dynamic Programming)

在这里插入图片描述

动态规划的常规步骤

在这里插入图片描述

相关概念

在这里插入图片描述

无后效性

在这里插入图片描述

有后效性

在这里插入图片描述

练习-找零钱

在这里插入图片描述
在这里插入图片描述

此题在leetcode动态规划的方法讲解:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
提交的代码:

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount+1];
        Arrays.fill(dp, amount+1);
        dp[0] = 0;
        for(int i=1; i<=amount; i++){
            for(int j=0; j<coins.length; j++){
                if(coins[j]<=i){
                    dp[i] = Math.min(dp[i], dp[i-coins[j]]+1);
                }
            }
        }

        return dp[amount] > amount ? -1 : dp[amount];
    }
}

做这题时发现leetcode上的Integer.MAX_VALUE是个负数

练习-最长递增子序列

在这里插入图片描述

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp = new int[nums.length];
        Arrays.fill(dp, 1);
        dp[0] = 1;
        int ans = 1;
        for(int i=1; i<nums.length; i++){
            for(int j=0; j<i; j++){
                if(nums[i] > nums[j]){
                    dp[i] = Math.max(dp[i], dp[j]+1);
                }
            }
            ans = Math.max(ans, dp[i]);
        }

        return ans;
    }
}

这道题目的核心就是dp[i]存的是以nums[i]为结尾的最长递增子序列。

练习-最长公共子序列(二维动态规划)

先看看leetcode上的讲解

在这里插入图片描述
在这里插入图片描述

提交的代码

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int[][] dp = new int[text1.length()+1][text2.length()+1];

        for(int i=1; i<=text1.length(); i++){
            for(int j=1; j<=text2.length(); j++){
                char c1 = text1.charAt(i-1);
                char c2 = text2.charAt(j-1);
                if(c1 == c2){
                    dp[i][j] = dp[i-1][j-1] + 1;
                }
                else{
                    dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }

        return dp[text1.length()][text2.length()];
    }
}

这道题经典二维动态规划的题目值得一背,最长公共子串同样可以用二维动态规划求解。

练习-0-1背包问题

在这里插入图片描述

leetcode上找不到题目,所以记住思路即可,0-1背包问题也是很经典的二维动态规划问题。

串(Sequence)

前缀、真前缀、后缀、真后缀

在这里插入图片描述

串匹配算法

在这里插入图片描述

蛮力法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

KMP

在这里插入图片描述

蛮力与KMP对比

在这里插入图片描述

KMP-next表的使用

在这里插入图片描述
在这里插入图片描述

KMP-核心原理

在这里插入图片描述

KMP-真前缀后缀的最大公共子串长度

在这里插入图片描述

KMP-得到next

在这里插入图片描述
在这里插入图片描述

KMP-得到next数组的代码设计

虽然不是java代码,但相信也是看得懂的

在这里插入图片描述

有了next数组,相信后面文本串和模式串匹配的主代码完全不是问题了

KMP-不足之处

在这里插入图片描述

KMP-优化思路

在这里插入图片描述

说白了就是,不断根据next表向前找,找到一个与当前pi指向元素不一样的元素为止,避免根据next数组得到一个与原本相同的元素,进行不必要的比较

KMP-性能分析

在这里插入图片描述

略显尴尬的是,暴力法其实也就O(nm)左右的时间复杂度,暴力法耗时也不长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸数得五

谢谢您的打赏勒

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值