LeetCode刷题之DP算法

技术LeetCode刷题之DP算法 LeetCode刷题之DP算法LeetCode刷题之动态规划算法
1.基本思路及代码框架
首先,动态规划的穷举有点特别,因为这类问题存在「重叠子问题」,如果暴力穷举的

LeetCode刷题的DP算法

LeetCode刷题之动态规划算法

1.基本思路及代码框架

首先,动态规划的穷尽有点特殊,因为如果这种问题在存在「重叠子问题」,被猛烈地穷尽,效率会极低,所以需要“备忘录”或“DP表”来优化穷尽过程,避免不必要的计算。

此外,动态规划问题必须是具备「最优子结构」,问题,以便通过子问题的最大值获得原问题的最大值。

此外,虽然动态规划的核心思想是穷尽最佳价值,但问题可能是千变万化的,要穷尽所有可行的解决方案并不容易。只有列出正确的「状态转移方程」,我们才能正确地穷尽它们。

上述重叠子问题、最优子结构和状态转移方程是动态规划的三个要素。你什么意思?我稍后会给你一个例子,但是在实际的算法问题中,写出状态转移方程是最困难的,这就是为什么很多朋友觉得动态规划问题很难。让我提供一个我开发的思维框架来帮助你思考状态转移方程:

明确 base case - 明确「状态」- 明确「选择」 - 定义 dp 数组/函数的含义.

按照上面的例程,最终的结果可以设置这个框架:

#初始化基本案例

dp[0][0][.]=基础

#进行状态转换。

对于状态1的所有值中的1:

状态2中状态2的所有值:

为.

Dp[国家1][国家2][.]=找到最大值(选项1,选项2.)

2.题目解答

1.LeetCode之509斐波拉且数列

解决方案思维

首先,递归函数是通过递归直接编写的。

第二,记录每一种情况,避免重复计算。

代码实现

1.递归方程

/*

* @ LC app=leet code . cn id=509 lang=CPP

*

* [509]斐波那契数

*/

//@lc代码=开始

解决方案类{

公众号:

int fib(int n){ 0

if (n==0)返回0;

if(n==1 | | n==2){ 0

返回1;

}

返回光纤(n -1)光纤(n-2);

}

};

//@lc代码=结束

2.子状态记录

解决方案类{

公众号:

int fib(int n){ 0

if(n==0){ 0

返回0;

}

int * DP=new int[n ^ 1];

DP[0]=0;DP[1]=1;

for(int I=2;I=n;I){ 0

DP[I]=DP[I-1]DP[I-2];

}

返回DP[n];

}

};

2.LeetCode之322零钱兑换

解决方案思维

动态编程用于解决问题,避免递归。找出基本状态、选择和目标。写出状态方程:

代码实现

解决方案类{

公众号:

int coinChange(矢量硬币,int金额){ 0

矢量dp(数量1,数量1);

DP[0]=0;

for(int I=0;I DP . size();I){ 0

for(自动硬币:硬币){ 0

if(I-coin 0){ 0

继续;

}

dp[i]=min(dp[i],1 DP[I-coin]);

}

}

退货(DP[金额]==金额1)-1 : DP[金额];

}

};

3.LeetCode之

300最长递增子序列

  • 解题思路

    状态转移方程:我们以dp[i]表示以num[i]结尾得最长递增子序列的长度。

    根据这个定义,我们的最终结果(子序列的最大长度)应该是 dp 数组中的最大值。

    int res = 0;
    for (int i = 0; i  dp.length; i++) {
        res = Math.max(res, dp[i]);
    }
    return res;
    

    nums[5] = 3,既然是递增子序列,我们只要找到前面那些结尾比 3 小的子序列,然后把 3 接到最后,就可以形成一个新的递增子序列,而且这个新的子序列长度加一

    显然,可能形成很多种新的子序列,但是我们只选择最长的那一个,把最长子序列的长度作为 dp[5] 的值即可。

    for (int i = 0; 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);
        }
    }
    
  • 代码实现

    /*
     * @lc app=leetcode.cn id=300 lang=cpp
     *
     * [300] 最长递增子序列
     */
    // @lc code=start
    class Solution {
    public:
        int lengthOfLIS(vectorint nums) {
            vectorint dp(nums.size(), 1);
            for (int i = 0; i  nums.size(); i++) {
                for (int j = 0; j  i; j++) {
                    if (nums[i]  nums[j]) {
                        dp[i] = max(dp[i], dp[j] + 1);
                    }
                }
            }
            int res = 0;
            for(int i = 0; i  nums.size(); i++) {
                res = max(res, dp[i]);
            }
            return res;
        }
    };
    // @lc code=end
    

4.LeetCode之1143最长公共子序列

  • 解题思路

    明确基础状态,写出状态,做出选择。

    写出状态方程。

  • 代码实现

    /*
     * @lc app=leetcode.cn id=1143 lang=cpp
     *
     * [1143] 最长公共子序列
     */
    // @lc code=start
    class Solution {
    public:
        int longestCommonSubsequence(string text1, string text2) {
            int m = text1.size(), n = text2.size();
            vectorvectorint dp(m + 1,vectorint(n + 1, 0));
            for (int i = 1; i = m; i++) {
                for (int j = 1; j = n; j++) {
                    if (text1[i - 1] == text2[j - 1]) {
                        dp[i][j] = 1 + dp[i - 1][j - 1];
                    } else {
                        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                    }
                }
            }
            return dp[m][n];
        }
    };
    // @lc code=end
    

5.LeetCode之583两个字符串的删除操作

  • 解题思路

    与上一题解法思路一致,只不过最终结果需要转化一下。

  • 代码实现

    /*
     * @lc app=leetcode.cn id=583 lang=cpp
     *
     * [583] 两个字符串的删除操作
     */
    // @lc code=start
    class Solution {
    public:
        int minDistance(string word1, string word2) {
            int m =word1.size(), n =word2.size();
            vectorvectorint dp(m + 1,vectorint(n + 1, 0));
            for (int i = 1; i = m; i++) {
                for (int j = 1; j = n; j++) {
                    if (word1[i - 1] ==word2[j - 1]) {
                        dp[i][j] = 1 + dp[i - 1][j - 1];
                    } else {
                        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                    }
                }
            }
            return m + n - 2 * dp[m][n];
        }
    };
    // @lc code=end
    

6.LeetCode之712两个字符串的最小ASCII删除和

  • 解题思路

    先给出基本状态,明确数组的含义,初始化数组,给出状态,做选择。

  • 代码实现

    /*
     * @lc app=leetcode.cn id=712 lang=cpp
     *
     * [712] 两个字符串的最小ASCII删除和
     */
    // @lc code=start
    class Solution {
    public:
        int minimumDeleteSum(string s1, string s2) {
            int m = s1.size(), n = s2.size();
            vectorvectorint dp(m + 1,vectorint(n + 1, 0));
            for (int i = m - 1; i = 0; i--) {
                dp[i][n] = dp[i + 1][n] + s1[i];
            }
            for (int j = n - 1; j = 0; j--) {
                dp[m][j] = dp[m][j + 1] + s2[j];
            }
            for (int i = m - 1; i = 0; i--) {
                for (int j = n -1; j = 0; j--) {
                    if (s1[i] == s2[j]) {
                        dp[i][j] = dp[i + 1][j + 1];
                    } else {
                        dp[i][j] = min(dp[i + 1][j] + s1[i],
                        dp[i][j + 1] + s2[j]);
                    }
                }
            }
            return dp[0][0];
        }
    };
    // @lc code=end
    

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/124343.html

(0)

相关推荐

  • java怎么设置每天定时任务的框架(java定时任务存在什么问题)

    技术java中常用的定时任务框架单体是怎样的本篇文章为大家展示了java中常用的定时任务框架单体是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、Timer+TimerT

    攻略 2021年12月21日
  • 如何进行null与index的分析

    技术如何进行null与index的分析这期内容当中小编将会给大家带来有关如何进行null与index的分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。今天在测试过程中遇到一问题, S

    攻略 2021年11月30日
  • Python学习笔记:pd.filter、query筛选数据

    技术Python学习笔记:pd.filter、query筛选数据 Python学习笔记:pd.filter、query筛选数据一、pd.filter函数
    1.介绍
    pd.filter 函数根据指定的索引

    礼包 2021年11月1日
  • 数据库中常见的术语是什么

    技术数据库中常见的术语是什么这期内容当中小编将会给大家带来有关数据库中常见的术语是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。数据库中常见的术语:字段使用过Office中的Exc

    攻略 2021年11月30日
  • MySQL 5.7怎么升级到8.0

    技术MySQL 5.7怎么升级到8.0这篇文章主要讲解了“MySQL 5.7怎么升级到8.0”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL 5.7怎么升级到8.

    攻略 2021年11月12日
  • yi的汉字,拼音“yi”都有哪些字

    技术yi的汉字,拼音“yi”都有哪些字一 乙 已 义 亿 弋 以 刈 忆 艺 失 仪 台 仡 议 伊 衣 圯 夷 钇 亦 屹 异 医 沂 诒 佁 矣 苡 佚 呓 役 抑 译 邑 依 祎 宜 怡 迤 饴 佾 峄 怿 易 绎

    生活 2021年10月28日