算法题2:动态规划

题目如下:

子数组的问题一般会想到滑动窗口或者快慢指针,但是输入的数组不是有序的,无法判断左右指针什么条件进行移动,当求最大或者最小、最优类似的问题时,适合用动态规划,动态回归需要找出状态转移方程。

1.什么是动态规划

基本步骤

  1. 定义状态
    明确问题的状态表示(例如 dp[i] 或 dp[i][j] 的含义)。
  2. 状态转移方程
    描述如何从子问题的解推导出当前问题的解(递推关系)。
  3. 初始化边界条件
    设置初始状态的值(如 dp[0] = 0)。
  4. 计算顺序
    确定填表顺序(自底向上或自顶向下)。
  5. 返回结果
    从状态表中提取最终解。

2.实现方式:

2.1 自顶向下(递归)

f(n) = f(n-1) + f(n-2)

f(n-1)与f(n-2)的计算过程和上面的公式一样

设置初始状态:f(0) = 0;f(1) = 1;

public class Solution {
    //使用哈希map,充当备忘录的作用
    Map<Integer, Integer> tempMap = new HashMap();
    public int numWays(int n) {
        // 先处理初始值,递归到初始值后就直接返回
        if (n == 0) {
            return 1;
        }
        if (n <= 2) {
            return n;
        }
        //先判断有没计算过,即看看备忘录有没有
        if (tempMap.containsKey(n)) {
            //备忘录有,即计算过,直接返回
            return tempMap.get(n);
        } else {
            
            tempMap.put(n, (numWays(n - 1) + numWays(n - 2)));
            return tempMap.get(n);
        }
    }
}

时间复杂度是O(n),空间复杂度O(n)

2.2 自底向上(迭代)

public class Solution {
    public int numWays(int n) {
        if (n<= 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        int a = 1;
        int b = 2;
        int temp = 0;
        //采用for循环的方式,只需要存储两个变量值即可
        for (int i = 3; i <= n; i++) {
            temp = a + b;
            a = b;
            b = temp;
        }
        return temp;
    }
    }

时间复杂度是O(n),空间复杂度O(1)

常见场景:青蛙跳台阶;斐波那契数列

回头查看最开始的题目,

分析:对于每一个元素num,都会有一个判断,num与pre+num比大小,pre表示num之前(包含num)与num中的最大值,如果num>pre+num,则丢弃之前的结果,直接采用num作为局部最大的和;另外采用maxSum变量存储全局最大和。

public class sulution{
    public int maxSubArray(int[] nums){
        if(nums.length == 1){
            return nums[0];
        }
        //maxSum用于存储当前元素之前的最大数据和
        int maxSum = nums[0];
        //用pre代表包含当前元素之前的最大数组和
        int pre = 0;
        
        for(int num : nums){
            pre = Math.max(pre + num,num);
            maxSum = Math.max(maxSum,pre);

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值