[算法] 动态规划 相关题目

1.定义

动态规划是分治思想的延伸,也就是大事化小,小事化了的意思

动态规划问题一般从这四个方面考虑:

1.状态定义:根据问题把子问题抽象出来

2.状态间的转移方程定义:状态与状态之间的递推关系

3.状态的初始化

4.返回结果

适用场景:最大值、最小值,可行不可行,是不是,方案个数

2.第一题Fibonacci 斐波那契数列

状态F(i):第 i 项的值

状态转移方程:F(i) = F(i - 1) + F(i - 2)

初始状态:F(0) = 0,F(1) = 1

返回结果:F(n)

代码表示:

public class Solution {
    // 时间复杂度O(n)
    public int Fibonacci(int n) {
        int[] arr = new int[n + 1];
        arr[0] = 0;
        arr[1] = 1;
        
        for(int i = 2;i <= n;i++){
            arr[i] = arr[i - 1] + arr[i - 2];
        }
        return arr[n];
    }
}

这是一个典型的动态规划,每一步都把之前的状态保存了下来,然后进行计算。

优化:可以优化一下空间复杂度,不用再前面定义了一个n + 1长度的数组

public class Solution {
    public int Fibonacci(int n) {
      if(n == 0){
          return 0;
      }
      if(n == 1){
          return 1;
      }
      int sum = 0;
      int n1 = 1;
      int n2 = 0;
        
      for(int i = 2;i <= n;i++){
          sum = n1 + n2;
          // 更新中间的状态
          n2 = n1;
          n1 = sum;
      }
        return sum;
    }
}

2.字符串分割

139. 单词拆分https://leetcode-cn.com/problems/word-break/

状态F(i):字符串前 i 个字符是否可以被分割

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true

F(4):前四个字符是否可以被分割:true

F(8):F(4) && 【5,8】是否可以在词典中找到:true

               F(0) && 【1,8】是否可以在词典中找到

               F(1) && 【2,8】是否可以在词典中找到

               F(2) && 【3,8】是否可以在词典中找到

               ...

               F(7) && 【8,8】是否可以在词典中找到

状态转移方程:F(i):j < i && F(j) && 【j + 1,i】是否可以在词典中找到

初始状态:F(0):true

返回结果:F(字符串长度):f(s.length())

代码表示:

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        boolean[] canBreak = new boolean[s.length() + 1];
        // 初始化
        canBreak[0] = true;

        for(int i = 1;i <= s.length();i++){
            // j < i && F(j) && [j + 1,i]
            for(int j = 0;j < i;j++){
                if(canBreak[j] && wordDict.contains(s.substring(j,i))){
                    canBreak[i] = true;
                    break;
                }
            }
        }
        return canBreak[s.length()];
    }
}

3.三角矩阵

三角形最小路径和_牛客题霸_牛客网【牛客题霸】收集各企业高频校招笔面试题目,配有官方题解,在线进行百度阿里腾讯网易等互联网名企笔试面试模拟考试练习,和牛人一起讨论经典试题,全面提升你的技术能力https://www.nowcoder.com/practice/c9d44b73dc7c4dbfa4272224b1f9b42c?tpId=196&tqId=39459&rp=1&ru=/exam/oj&qru=/exam/oj&sourceUrl=%2Fexam%2Foj%3Ftab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196%26page%3D1%26search%3D%25E4%25B8%2589%25E8%25A7%2592&difficulty=undefined&judgeStatus=undefined&tags=&title=%E4%B8%89%E8%A7%92

public int minTrace (int[][] triangle) {
        int len = triangle.length;
        if (len == 0) return 0;

        // f(i,j)=Min{f(i+1,j), f(i+1,j+1)} + val(i, j)
        int[][] array = new int[len][len];
        for (int i = len-1; i >= 0; i--) {
            for (int j = 0; j <= i; j++) {
                if (i == len-1) {
                    array[i][j] = triangle[i][j];
                } else {
                    array[i][j] = Math.min(array[i+1][j], array[i+1][j+1]) + triangle[i][j];
                }
            }
        }
        return array[0][0];
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值