当前位置: 首页 > news >正文

【leetcode hot 100 152】乘积最大子数组

错误解法:db[i]表示以i结尾的最大的非空连续,动态规划:dp[i] = Math.max(nums[i], nums[i] * dp[i - 1]);

class Solution {
    public int maxProduct(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n]; // db[i]表示以i结尾的最大的非空连续
        dp[0] = nums[0];
        for (int i = 1; i < n; i++) {
            dp[i] = Math.max(nums[i], nums[i] * dp[i - 1]);
            // 不需要循环,直接用dp[i-1]判断即可
            // int curr_max = nums[i];
            // dp[i] = nums[i];   // 赋初始值
            // for(int j = i-1; j>=0; j--) {
            //     curr_max = curr_max * nums[j];
            //     dp[i] = Math.max(dp[i], curr_max);
            // }
        }
        return Arrays.stream(dp).max().getAsInt();
    }
}

错误原因:未考虑负数情况

在这里插入图片描述

解法一:(动态规划)①定义:dp[i]表示以下标为i的连续子数组最大乘积,dp[n];dp_helperi表示以下标为i的连续子数组最小乘积 ②初始状态:dp[0]=nums[0] dp_helper[0]=0 ③状态转移方程:dp[i] = Math.max(dp[i-1],dp[i-1]*nums[i],dp_helper[i-1]*nums[i]);dp_helper[i] = Math.min(dp_helper[i-1],dp[i-1]*nums[i],dp_helper[i-1]*nums[i])

考虑当前位置如果是一个负数的话,那么我们希望以它前一个位置结尾的某个段的积也是个负数,这样就可以负负得正,并且我们希望这个积尽可能「负得更多」,即尽可能小。如果当前位置是一个正数的话,我们更希望以它前一个位置结尾的某个段的积也是个正数,并且希望它尽可能地大。于是这里我们可以再维护一个 f m i n ( i ) f_{min}(i) fmin(i),它表示以第 i i i个元素结尾的乘积最小子数组的乘积,那么我们可以得到这样的动态规划转移方程:
在这里插入图片描述

import java.util.*;

/**
 * @author longyy
 * @version 1.0
 */
class Solution79 {
    public int maxProduct(int[] nums) {
        // 定义:dp[i]表示以下标为i的连续子数组最大乘积,dp[n];dp_helper[i]表示以下标为i的连续子数组最小乘积
        // dp_helper[i](应对两个负数乘积更大的情况)
        // 初始状态:dp[0]=nums[0] dp_helper[0]=0
        // 状态转移方程:dp[i] = Math.max(dp[i-1],dp[i-1]*nums[i],dp_helper[i-1]*nums[i])
        //             dp_helper[i] = Math.min(dp_helper[i-1],dp[i-1]*nums[i],dp_helper[i-1]*nums[i])
        int n = nums.length;
        int[] dp = new int[n]; // db[i]表示以i结尾的最大的非空连续
        int[] dp_helper = new int[n]; // db[i]表示以i结尾的最小的非空连续
        dp[0] = nums[0];
        for (int i = 1; i < n; i++) {
            dp[i] = Math.max(Math.max(nums[i], nums[i] * dp[i - 1]), nums[i]*dp_helper[i-1]);
            dp_helper[i] = Math.min(Math.min(nums[i], nums[i]*dp_helper[i-1]), nums[i]*dp[i-1]);
        }
        return Arrays.stream(dp).max().getAsInt();
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] nums = new int[n];
        for(int nums_i=0; nums_i < n; nums_i++){
            nums[nums_i] = in.nextInt();
        }
        Solution79 solution79 = new Solution79();
        System.out.println(solution79.maxProduct(nums));
    }
}

相关文章:

  • OpenCV图像形态学详解
  • 树莓派4B配置wifi热点,可访问http协议
  • 不再卡顿!如何根据使用需求挑选合适的电脑内存?
  • ViewModel vs AndroidViewModel:核心区别与使用场景详解
  • 云服务器10M带宽实际速度能达到多少?
  • 大唐杯省赛安排来了!还有7天,该如何准备?
  • BERT、T5、ViT 和 GPT-3 架构概述及代表性应用
  • 《从零搭建Vue3项目实战》(AI辅助搭建Vue3+ElemntPlus后台管理项目)零基础入门系列第十篇:商品管理功能实现
  • MOS管的发热原因和解决办法
  • TGRS 2024 | 基于光谱相关的高光谱图像超分辨率融合网络
  • 开源Cursor替代品——Void
  • 二维偏序-蓝桥20102,没写完
  • 996引擎-源码学习:PureMVC Lua 中的 Facade 类
  • 【状态适配器模式:级联选择器多状态数据处理完整解决方案】
  • layui中transfer两个table展示不同的数据列
  • 基于RV1126开发板实现多路网络摄像头取流方案
  • 设计模式:策略模式 - 消除复杂条件判断的利器
  • 【算法】——会了二分查找,对O(logn)真的很敏感
  • LabVIEW 中 “Flatten To Json String” VI 应用及优势
  • 【C++取经之路】lambda和bind
  • 做网站建设业务员好吗/百度指数查询平台
  • 营销网站建设联系方式/新站seo快速排名 排名
  • 如何做高网站的浏览量/百度经验首页官网
  • 网站建设自/百度指数免费查询
  • wordpress文章标题前显示置顶/钦州seo
  • jsp做购物网站技术可行性/广州网站设计实力乐云seo