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)

相关推荐

  • 文件夹选项怎么打开,怎么把文件夹选项找回来呀。。

    技术文件夹选项怎么打开,怎么把文件夹选项找回来呀。。让“文件夹选项”显示的方法有两个文件夹选项怎么打开。 方法一:组策略 点击“开始→运行”,在运行对话框中输入“gpedit.msc”命令,点击“确定”按钮后,弹出“组策

    生活 2021年10月28日
  • 怎么使用物联网设备来确保儿童安全

    技术怎么使用物联网设备来确保儿童安全这篇文章将为大家详细讲解有关怎么使用物联网设备来确保儿童安全,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。IoT 设备是什么?IoT 设备是指那些在

    攻略 2021年10月26日
  • 网络设备配置对比

    技术网络设备配置对比 网络设备配置对比#!/usr/bin
    # _*_ coding: UTF-8 _*_
    # Copyright (c) 2021 GengYu.All rights reserved

    礼包 2021年12月16日
  • CALMS及其与数据库DevOps的关系是什么

    技术CALMS及其与数据库DevOps的关系是什么CALMS及其与数据库DevOps的关系是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获

    攻略 2021年12月1日
  • 鳄鱼属于哺乳动物吗,哺乳动物一定是胎生的吗

    技术鳄鱼属于哺乳动物吗,哺乳动物一定是胎生的吗否鳄鱼属于哺乳动物吗。1.现代观点认为,哺乳动物不是由爬行动物进化来的,哺乳动物祖先和现代爬行动物以及鸟类的祖先是两条单独的进化路线。哺乳动物祖先属于广义上的爬行动物,但这种

    生活 2021年10月23日
  • 农村医保网上如何缴费,农村医疗保险网上怎么交

    技术农村医保网上如何缴费,农村医疗保险网上怎么交人登录市地税局网站后农村医保网上如何缴费,可通过“网上办税(费)厅”,进入“自助缴费”模块,采用“银税转账”或“网上银行”两种划款方式完成缴费。1.若使用“银税转账”方式,

    生活 2021年10月30日