[Algorithm][动态规划][子数组/子串问题][最大子数组和][环形子数组的最大和][乘积最大子数组][乘积为正数的最长子数组长度]详细讲解

本文主要是介绍[Algorithm][动态规划][子数组/子串问题][最大子数组和][环形子数组的最大和][乘积最大子数组][乘积为正数的最长子数组长度]详细讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1.最大子数组和
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.环形子数组的最大和
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 3.乘积最大子数组
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 4.乘积为正数的最长子数组长度
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


1.最大子数组和

1.题目链接

  • 最大子数组和

2.算法原理详解

  • 思路
    • 确定状态表示 -> dp[i]的含义

      • i位置元素为结尾的所有子数组中的最大和
        请添加图片描述
    • 推导状态转移方程

      • dp[i] = max(nums[i], dp[i - 1] + nums[i])
        请添加图片描述
    • 初始化:dp表多开一个虚拟结点,避免处理边界

      • dp[0] = 0
    • 确定填表顺序:从左往右

    • 确定返回值:整个dp表里的最大值


3.代码实现

int maxSubArray(vector<int>& nums) 
{int n = nums.size();vector<int> dp(n + 1);dp[0] = 0;int ret = INT_MIN;for(int i = 1; i <= n; i++){dp[i] = max(nums[i - 1], dp[i - 1] + nums[i - 1]);ret = max(ret, dp[i]);}return ret;
}

2.环形子数组的最大和

1.题目链接

  • 环形子数组的最大和

2.算法原理详解

  • 本题因为有环形数组,问题并不好处理,但是可以将问题转化为最大子数组和

    • 若最大子数组和出现在中间,则与最大子数组和解法无异
    • 若最大子数组和出现在两边,则可以将问题转化为找中间的最小子数组和
    • 两个情况合并,找其中的最大和即可
      请添加图片描述
  • 思路

    • 确定状态表示 -> dp[i]的含义

      • f[i]:以i位置元素为结尾的所有子数组中的最大和
      • g[i]:以i位置元素为结尾的所有子数组中的最小和
        请添加图片描述
    • 推导状态转移方程

      • f[i] = max(nums[i], f[i - 1] + nums[i])
      • g[i] = min(nums[i], g[i - 1] + nums[i])
        请添加图片描述
    • 初始化:dp表多开一个虚拟结点,避免处理边界

      • f[0] = g[0] = 0 -> 确保dp[0]的值,不会影响后面的求和
    • 确定填表顺序:从左往右

    • 确定返回值:sum == gmin ? fmax : max(fmax, sum - gmin)


3.代码实现

int maxSubarraySumCircular(vector<int>& nums) 
{int n = nums.size();vector<int> f(n + 1);vector<int> g(n + 1);int fmax = INT_MIN, gmin = INT_MAX, sum = 0;for(int i = 1; i <= n; i++){int x = nums[i - 1];sum += x;f[i] = max(x, x + f[i - 1]);fmax = max(fmax, f[i]);g[i] = min(x, x + g[i - 1]);gmin = min(gmin, g[i]);}return sum == gmin ? fmax : max(fmax, sum - gmin);
}

3.乘积最大子数组

1.题目链接

  • 乘积最大子数组

2.算法原理详解

  • 思路
    • 确定状态表示 -> dp[i]的含义

      • f[i]:以i位置元素为结尾的所有子数组中的最大乘积
      • g[i]:以i位置元素为结尾的所有子数组中的最小乘积
        请添加图片描述
    • 推导状态转移方程

      • f[i] = max(nums[i], f[i - 1] * nums[i], g[i - 1] * nums[i])
      • g[i] = min(nums[i], f[i - 1] * nums[i], g[i - 1] * nums[i])
        请添加图片描述
    • 初始化:dp表多开一个虚拟结点,避免处理边界

      • f[0] = g[0] = 1 -> 确保dp[0]的值,不会影响后面的乘积
    • 确定填表顺序:从左往右

    • 确定返回值:f表里的最大值


3.代码实现

int maxProduct(vector<int>& nums) 
{int n = nums.size();vector<int> f(n + 1), g(n + 1);f[0] = g[0] = 1;int ret = INT_MIN;for(int i = 1; i <= n; i++){f[i] = max(nums[i - 1], max(f[i - 1] * nums[i - 1], g[i - 1] * nums[i - 1]));g[i] = min(nums[i - 1], min(f[i - 1] * nums[i - 1], g[i - 1] * nums[i - 1]));ret = max(ret, f[i]);}return ret;
}

4.乘积为正数的最长子数组长度

1.题目链接

  • 乘积为正数的最长子数组长度

2.算法原理详解

  • 思路
    • 确定状态表示 -> dp[i]的含义

      • f[i]:以i位置元素为结尾的所有子数组中,乘积为正数的最长长度
      • g[i]:以i位置元素为结尾的所有子数组中,乘积为负数的最长长度
        请添加图片描述
    • 推导状态转移方程
      请添加图片描述

    • 初始化:dp表多开一个虚拟结点,避免处理边界

      • f[0] = g[0] = 0
    • 确定填表顺序:从左往右,两个表一起填

    • 确定返回值:f表里的最大值


3.代码实现

int getMaxLen(vector<int>& nums) 
{int n = nums.size();vector<int> f(n + 1), g(n + 1);int ret = INT_MIN;for(int i = 1; i <= n; i++){if(nums[i - 1] > 0){f[i] = f[i - 1] + 1;g[i] = g[i - 1] == 0 ? 0 : g[i - 1] + 1;}else if(nums[i - 1] < 0){f[i] = g[i - 1] == 0 ? 0 : g[i - 1] + 1;g[i] = f[i - 1] + 1;}ret = max(ret, f[i]);}return ret;
}

这篇关于[Algorithm][动态规划][子数组/子串问题][最大子数组和][环形子数组的最大和][乘积最大子数组][乘积为正数的最长子数组长度]详细讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1012991

相关文章

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

通过Docker Compose部署MySQL的详细教程

《通过DockerCompose部署MySQL的详细教程》DockerCompose作为Docker官方的容器编排工具,为MySQL数据库部署带来了显著优势,下面小编就来为大家详细介绍一... 目录一、docker Compose 部署 mysql 的优势二、环境准备与基础配置2.1 项目目录结构2.2 基

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

如何解决Spring MVC中响应乱码问题

《如何解决SpringMVC中响应乱码问题》:本文主要介绍如何解决SpringMVC中响应乱码问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC最新响应中乱码解决方式以前的解决办法这是比较通用的一种方法总结Spring MVC最新响应中乱码解