5.29 单词拆分 && 乘积最大(动态规划)

单词拆分

原理思想:完全背包

1.确定dp数组以及下标的含义

**dp[i] : 字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词**。

2. 确定递推公式

如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。(j < i )。

所以递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] = true。

3.dp数组如何初始化

从递归公式中可以看出,dp[i] 的状态依靠 dp[j]是否为true,那么dp[0]就是递归的根基,dp[0]一定要为true,否则递归下去后面都都是false了

    public boolean wordBreak(String s, List<String> wordDict) {
    	boolean[] dp=new boolean[s.length()+1];
    	dp[0]=true;
    	for(int i=1; i<s.length()+1; i++)
    		for(int j=0; j<i; j++) {
    			if(dp[j]==true && wordDict.contains(s.substring(j, i))) {
    				dp[i]=true;
    			}
    		}
    	return dp[s.length()];
    }

乘积最大

原理思想:

 

    public int maxProduct(int[] nums) {
    	int[] dpMax=new int[nums.length]; //存储前i个数乘积的最大值
    	int[] dpMin=new int[nums.length]; //存储前i个数乘积的最小值
    	dpMax[0]=dpMin[0]=nums[0];
    	int max=nums[0]; //最终的最大值
    	for(int i=1; i<nums.length; i++) {
    		//更新最大和最小乘积值
    		dpMax[i]=Math.max(dpMin[i-1]*nums[i], Math.max(dpMax[i-1]*nums[i], nums[i]));
    		dpMin[i]=Math.min(dpMin[i-1]*nums[i], Math.min(dpMax[i-1]*nums[i], nums[i]));
    		//更新当前对大的连续子乘积
    		max=Math.max(dpMax[i], max);
    	}
    	return max;
    }

其实可以不需要这个dp数组,只需要额外变量存储即可,因为更新 dp[i] 的时候,我们只用到 dp[i-1] 的信息,再之前的信息就用不到了。所以我们完全不需要一个数组,只需要一个变量去重复覆盖更新即可

public int maxProduct(int[] nums) {
    int n = nums.length;
    if (n == 0) {
        return 0;
    }
    int dpMax = nums[0];
    int dpMin = nums[0];
    int max = nums[0];
    for (int i = 1; i < n; i++) {
        //更新 dpMin 的时候需要 dpMax 之前的信息,所以先保存起来
        int preMax = dpMax;
        dpMax = Math.max(dpMin * nums[i], Math.max(dpMax * nums[i], nums[i]));
        dpMin = Math.min(dpMin * nums[i], Math.min(preMax * nums[i], nums[i]));
        max = Math.max(max, dpMax);
    }
    return max;

作者:windliang
链接:https://leetcode.cn/problems/maximum-product-subarray/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by--36/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值