热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[C++]LeetCode:96最大子数组乘积(动态规划算法详解)

题目要求在给定的数组中找到一个连续子数组,使其乘积最大。本文详细介绍了使用动态规划算法解决这一问题的方法,包括状态定义、状态转移方程和初始化步骤。通过具体的例子和代码实现,帮助读者深入理解该算法的核心思想和实现细节。
题目:

Find the contiguous subarray within an array (containing at least one number) which has the largest product.

For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.

思路:

这道题和Maximum Subarray解法类似,维护两个变量来动态规划,一个局部最优,一个全局最优。第i步的局部最优,表示的是必须包含A[i-1](当前元素)的局部最优解,全局最优是到当前元素为止的最优值。讨论动态规划的递推式,假设我们已知第i步的global[i]和local[i],第i+1步的表达式:local[i+1] = max(A[i], local[i]+A[i]), 局部最优必须包含当前元素,所以是上一步的局部最优(包含上一个数组元素)local[i]+当前元素A[i](local[i] 包含第i个元素,A[i]是第i+1个元素,这样计算是符合题设的),如果local[i]是负值,则加上它无法保证当前局部最优,所以取A[i]. global[i+1] = max(global[i], local[i+1]). 有了当前一步的局部最优,那全局最优就是当前的局部最优或者还是原来的全局最优(全局最优始终维护着所有解的最优解,包含所有情况,如果最优解不包含当前元素,那么前面会被维护在全局最优解里,如果包含当前元素,此时的解就是局部最优)

根据以上的分析,我们可以得到 Maximum SubarrayAC Code:

class Solution {
public:
    int maxSubArray(int A[], int n) {
        if(n == 0) return 0;
        int local = A[0];
        int global = A[0];
        
        for(int i = 1; i 
现在我们来分析下这道题,这道题模型和思路都和上道题很类似 ,还是用一维动态规划中的“局部最优和全局最优法“。不同的是,我们需要考虑乘法的特性,只是维护一个局部最优不足以得到后面的全局最优。因为乘法和加法不同,累加结果只要是正就一定递增,乘法可能上一个结果为负值,后面再出现(不需要相邻)另外一个负数相乘就会得到更大的乘积(负负为正)。所以我们这里需要维护三个变量,局部最大,局部最小,全局最大。局部最大的定义,维护从0~k,包含当前元素的局部最大(一定包含k)。

f(k) = Largest product subarray, from index 0 up to k.

接下来,我们来看下递推公式:假设我们得到了第i 步的当前的局部最大maxlocal[i], 局部最小minlocal[i], 全局最大global[i]. 则第i+1步的局部最大maxlocal[i+1] = max( A[i], maxlocal[i] * A[i],  minlocal[i] * A[i]), minlocal[i+1] = min(A[i], maxlocal[i] *A[i], minlocal[i]*A[i]), global[i+1] = max(maxlocal, global); 得到了递推公式,接下来我们就可以敲代码了。这道题是个不错的面试题目,上道题比较常见,这道题模型相似,又有新的考点。还能考察动态规划,需要我们面对具体的问题,仔细分析和思考,彻底理解了方法,才能做到举一而反三。

Attention:

1. 注意此题中是乘法,需要考虑乘法的特性,需要多维护一个变量minlocal.

2. 注意我们动态规划时,求解minlocal[i+1]时使用的时上一个maxlocal[i], 所以需要在局部最优更新前,先保存maxlocal[i]

int maxcopy = maxlocal;
            maxlocal = max(max(maxlocal*A[i], A[i]), minlocal*A[i]);
            minlocal = min(min(maxcopy*A[i], A[i]), minlocal*A[i]);
            global = max(maxlocal, global);

3. 特殊情况,不能忘记,假如数组没有元素,返回0.

4. max 和min函数的参数是两个值,只能两个值作比较,所以要两次调用函数。

maxlocal = max(max(maxlocal*A[i], A[i]), minlocal*A[i]);
minlocal = min(min(maxcopy*A[i], A[i]), minlocal*A[i]);

复杂度:O(n)

AC Code:

class Solution {
public:
    int maxProduct(int A[], int n) {
        if(n == 0) return 0;
        if(n == 1) return A[0];
        
        int maxlocal = A[0];
        int minlocal = A[0];
        int global = A[0];
        
        for(int i = 1; i 


[C++]LeetCode: 96 Maximum Product Subarray(动态规划)


推荐阅读
  • 嵌套列表的扁平化处理
    本文介绍了一种方法,用于遍历嵌套列表中的每个元素。如果元素是整数,则将其添加到结果数组中;如果元素是一个列表,则递归地遍历这个列表。此方法特别适用于处理复杂数据结构中的嵌套列表。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • 本文介绍了如何通过C#语言调用动态链接库(DLL)中的函数来实现IC卡的基本操作,包括初始化设备、设置密码模式、获取设备状态等,并详细展示了将TextBox中的数据写入IC卡的具体实现方法。 ... [详细]
  • 本文详细介绍了C++中的构造函数,包括其定义、特点以及如何通过构造函数进行对象的初始化。此外,还探讨了转换构造函数的概念及其在不同情境下的应用,以及如何避免不必要的隐式类型转换。 ... [详细]
  • 本文将从基础概念入手,详细探讨SpringMVC框架中DispatcherServlet如何通过HandlerMapping进行请求分发,以及其背后的源码实现细节。 ... [详细]
  • Windows操作系统提供了Encrypting File System (EFS)作为内置的数据加密工具,特别适用于对NTFS分区上的文件和文件夹进行加密处理。本文将详细介绍如何使用EFS加密文件夹,以及加密过程中的注意事项。 ... [详细]
  • importjava.io.*;importjava.util.*;publicclass五子棋游戏{staticintm1;staticintn1;staticfinalintS ... [详细]
  • 解决Visual Studio Code中PHP Intelephense误报问题
    PHP作为一种高度灵活的编程语言,其代码结构可能导致Intelephense插件在某些情况下报告不必要的错误或警告。自1.3.3版本起,Intelephense引入了多个配置选项,允许用户根据具体的工作环境和编程风格调整这些诊断信息的显示。 ... [详细]
  • Bootstrap Paginator 分页插件详解与应用
    本文深入探讨了Bootstrap Paginator这款流行的JavaScript分页插件,提供了详细的使用指南和示例代码,旨在帮助开发者更好地理解和利用该工具进行高效的数据展示。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • 本文介绍了SIP(Session Initiation Protocol,会话发起协议)的基本概念、功能、消息格式及其实现机制。SIP是一种在IP网络上用于建立、管理和终止多媒体通信会话的应用层协议。 ... [详细]
  • 本文详细介绍了JQuery Mobile框架中特有的事件和方法,帮助开发者更好地理解和应用这些特性,提升移动Web开发的效率。 ... [详细]
  • 本文详细介绍了如何在ARM架构的目标设备上部署SSH服务端,包括必要的软件包下载、交叉编译过程以及最终的服务配置与测试。适合嵌入式开发人员和系统集成工程师参考。 ... [详细]
  • c语言二元插值,二维线性插值c语言
    c语言二元插值,二维线性插值c语言 ... [详细]
author-avatar
qlongjun
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有