zoukankan      html  css  js  c++  java
  • 五大常用算法--DP

    概念

    【geekforgeeks】

    Dynamic Programming is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of subproblems, so that we do not have to re-compute them when needed later. This simple optimization reduces time complexities from exponential to polynomial. For example, if we write simple recursive solution for Fibonacci Numbers, we get exponential time complexity and if we optimize it by storing solutions of subproblems, time complexity reduces to linear.

    动态规划是对于单纯的递归的一个主要优化方法。当我们看到递归解法对于同一个输入重复调用时,我们能通过动态规划方法重复优化。方法是简单存储子问题的结果,这样我们在后序用到它们的时候就不需要再重复计算了。这个简单的优化将时间复杂度从指数减少到了多项式。比如,如果我们写一下fibonacci数列的简单递归解法,我们得到了指数的时间复杂性,但是如果我们通过存储子问题进行优化,时间复杂性减少到了线性。

    应用场景

    通用解体思路

    动态规划四要素:

    1. 状态

    2. 状态转移方程

    3. 初始化

    4. 结果

    题目练习

    Fibonacci数列 leetcode 509

    最大连续子序列 leetcode 53

    // 输入: [-2,1,-3,4,-1,2,1,-5,4],
    // 输出: 6
    // 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
    class Solution {
      public int maxSubArray(int[] nums) {
        int n = nums.length, maxSum = nums[0];
        for(int i = 1; i < n; ++i) {
          if (nums[i - 1] > 0) nums[i] += nums[i - 1];
          maxSum = Math.max(nums[i], maxSum);
        }
        return maxSum;
      }
    }

    通配符匹配 leetcode 44

    // 输入:
    // s = "adceb"
    // p = "*a*b"
    // 输出: true
    // 解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".
    
    class Solution {
        public boolean isMatch(String s, String p) {
            int m = s.length(), n = p.length();
            boolean[][] f = new boolean[m + 1][n + 1];
            
            f[0][0] = true;
            for(int i = 1; i <= n; i++){
                f[0][i] = f[0][i - 1] && p.charAt(i - 1) == '*';
            }
            
            for(int i = 1; i <= m; i++){
                for(int j = 1; j <= n; j++){
                    if(s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?'){
                        f[i][j] = f[i - 1][j - 1];
                    }
                    if(p.charAt(j - 1) == '*'){
                        f[i][j] = f[i][j - 1] || f[i - 1][j];
                    }
                }
            }
            return f[m][n];
        }
    }

    参考资料

    1. https://www.geeksforgeeks.org/dynamic-programming/

    2. https://leetcode-cn.com/problems/wildcard-matching/solution/dong-tai-gui-hua-si-yao-su-by-a380922457-4/

    3. https://leetcode-cn.com/problems/maximum-subarray/solution/zui-da-zi-xu-he-by-leetcode/

  • 相关阅读:
    [学习笔记]Senparc.CO2NET 缓存使用笔记
    [解决方案]Senparc.CO2NET 初始编译报错的问题
    [解决方案]NuGet打包报错: 'X' already has a dependency defined for 'Y'
    [经验分享]Windows系统下生成IOS证书
    struct redisServer’ has no member named ‘maxmemory’
    事务提交后执行异步方法
    restTemplate 401 Unauthorized: [no body]
    flyway不创建表
    启动kinaba并在后台运行
    springboot admin邮件报警
  • 原文地址:https://www.cnblogs.com/harry1989/p/12089488.html
Copyright © 2011-2022 走看看