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)

相关推荐

  • C语言怎么实现单链表的基本功能

    技术C语言怎么实现单链表的基本功能本篇内容主要讲解“C语言怎么实现单链表的基本功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言怎么实现单链表的基本功能”吧!1.首先简

    攻略 2021年11月24日
  • 抖音刷粉网址,抖音刷粉丝靠谱平台

    技术抖音刷粉网址,抖音刷粉丝靠谱平台抖音怎么涨粉丝比较快,抖音怎么做才会涨粉丝,学着点!抖音是一款深受大众喜欢的短视频app,虽然已经出现几年了,但是有很多用户的粉丝还是没有多少个。抖音刷粉平台有吗?这个肯定有的,而且有

    测评 2021年10月20日
  • 抖音请人刷粉,刷抖音粉丝网站最便宜?

    技术抖音请人刷粉,刷抖音粉丝网站最便宜?抖音便宜刷粉网站,刷抖音粉丝网站最便宜抖音刷粉丝的平台网站搜索应该也很多,价格差异也很大,原因主要是看做单的号的质量,有的机器刷单,有的是真人接单,有的是群派单,还有的是真机养的号

    测评 2021年10月19日
  • 网页原型图设计工具用什么(网页的原型设计如何使用)

    技术如何用浏览器给网站设计原型如何用浏览器给网站设计原型,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。给网站设计原型是一个全面系统的过程,在此过程中你需

    攻略 2021年12月22日
  • Java多线程程序初步设计方法是什么

    技术Java多线程程序初步设计方法是什么本篇内容主要讲解“Java多线程程序初步设计方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java多线程程序初步设计方法是什

    攻略 2021年11月20日
  • 配置python环境中遇到的一些问题

    技术配置python环境中遇到的一些问题 配置python环境中遇到的一些问题这是个人第一次发博客,想分享一下在配置python中出现的一些问题。
    在cmd或Anaconda命令行中操作的。
    pip使用

    礼包 2021年12月20日