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)

相关推荐

  • openwrt可以用主路由器吗(openwrt怎样连接网络)

    技术OpenWRT如何连上路由器这篇文章将为大家详细讲解有关OpenWRT如何连上路由器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。连上路由器 刚刚刷好 OpenWRT 的

    攻略 2021年12月18日
  • ibatis怎么多条件查询(ibatis优点)

    技术iBATIS发展方向的四个方面分别是什么这期内容当中小编将会给大家带来有关iBATIS发展方向的四个方面分别是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。iBATIS发展方向

    攻略 2021年12月19日
  • MySQL5.6.x sha256_password插件登入用户时报错怎么办

    技术MySQL5.6.x sha256_password插件登入用户时报错怎么办MySQL5.6.x sha256_password插件登入用户时报错怎么办,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因

    攻略 2021年10月26日
  • ros 作用(ros系统中定义的消息在哪里)

    技术ROS中的cmake指的是什么ROS中的cmake指的是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。这一次讨论ROS中的cmake和ROS代码

    攻略 2021年12月23日
  • ADO.NET事务处理方法有哪些

    技术ADO.NET事务处理方法有哪些这篇文章主要介绍“ADO.NET事务处理方法有哪些”,在日常操作中,相信很多人在ADO.NET事务处理方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家

    攻略 2021年12月3日
  • react: 高阶函数及函数柯里化

    技术react: 高阶函数及函数柯里化 react: 高阶函数及函数柯里化1.高阶函数若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。
    若A函数,调用的返回值依然是一个函数,那么A就可以称之

    礼包 2021年12月2日