算法面试真题详解:最大子数组 II

简介: 算法面试真题详解:最大子数组 II

描述
给定一个整数数组,找出两个 不重叠 子数组使得它们的和最大。
每个子数组的数字在数组中的位置应该是连续的。
返回最大的和。

在线评测地址:领扣题库官网

样例 1:
输入:
[1, 3, -1, 2, -1, 2]
输出:
7
解释:
最大的子数组为 [1, 3] 和 [2, -1, 2] 或者 [1, 3, -1, 2] 和 [2].

···
样例2:
输入:
[5,4]
输出:
9
解释:
最大的子数组为 [5] 和 [4].
···
挑战
要求时间复杂度为 O(n)

解题思路

这题是最大子段和的升级版。我们只要在求最大子段和的基础上,计算出前后缀的最大子段和,就可以枚举分界点来计算结果。

代码思路

对于前缀的最大子段和,我们可以先求以i位置为结尾的最大子段和的值leftMax[i]。

max中的两个参数分别代表延续前一个为结尾的最大字段和,或者当前的nums[i]成为一段新的子段的两种情况。
计算前缀最大子段和prefixMax,计算前缀最大值即可。

后缀的值也同理进行计算。
最后枚举分界点,取最大值,最终的结果为:

复杂度分析

设数组长度为N。
只需常数次地遍历数组,时间复杂度为O(N)。
需要常数个额外数组来记录当前位置结尾前后缀最大连续和以及前后缀最大连续和,空间复杂度为O(N)。

public class Solution {
    /*
     * @param nums: A list of integers
     * @return: An integer denotes the sum of max two non-overlapping subarrays
     */
    public int maxTwoSubArrays(List<Integer> nums) {
        int n = nums.size();
        
        // 计算以i位置为结尾的前后缀最大连续和
        List<Integer> leftMax = new ArrayList(nums);
        List<Integer> rightMax = new ArrayList(nums);
        
        for (int i = 1; i < n; i++) {
            leftMax.set(i, Math.max(nums.get(i), nums.get(i) + leftMax.get(i - 1)));
        }
        
        for (int i = n - 2; i >= 0; i--) {
            rightMax.set(i, Math.max(nums.get(i), nums.get(i) + rightMax.get(i + 1)));
        }
        
        // 计算前后缀部分的最大连续和
        List<Integer> prefixMax = new ArrayList(leftMax);
        List<Integer> postfixMax = new ArrayList(rightMax);
        
        for (int i = 1; i < n; i++) {
            prefixMax.set(i, Math.max(prefixMax.get(i), prefixMax.get(i - 1)));
        }
        
        for (int i = n - 2; i >= 0; i--) {
            postfixMax.set(i, Math.max(postfixMax.get(i), postfixMax.get(i + 1)));
        }
        
        int result = Integer.MIN_VALUE;
        for (int i = 0; i < n - 1; i++) {
            result = Math.max(result, prefixMax.get(i) + postfixMax.get(i + 1));
        }
        
        return result;
    }
}

更多题解参考:九章官网solution

相关文章
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
232 0
|
算法
面试场景题:如何设计一个抢红包随机算法
本文详细解析了抢红包随机算法的设计与实现,涵盖三种解法:随机分配法、二倍均值法和线段切割法。随机分配法通过逐次随机分配金额确保总额不变,但易导致两极分化;二倍均值法优化了金额分布,使每次抢到的金额更均衡;线段切割法则将总金额视为线段,通过随机切割点生成子金额,手气最佳金额可能更高。代码示例清晰,结果对比直观,为面试中类似算法题提供了全面思路。
2178 16
|
存储 人工智能 算法
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
982 23
|
存储 监控 算法
关于员工上网监控系统中 PHP 关联数组算法的学术解析
在当代企业管理中,员工上网监控系统是维护信息安全和提升工作效率的关键工具。PHP 中的关联数组凭借其灵活的键值对存储方式,在记录员工网络活动、管理访问规则及分析上网行为等方面发挥重要作用。通过关联数组,系统能高效记录每位员工的上网历史,设定网站访问权限,并统计不同类型的网站访问频率,帮助企业洞察员工上网模式,发现潜在问题并采取相应管理措施,从而保障信息安全和提高工作效率。
254 7
|
算法 安全 Java
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
729 16
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩分享分库分表的基因算法设计,涵盖分片键选择、水平拆分策略及基因法优化查询效率等内容,助力面试者应对大厂技术面试,提高架构设计能力。
美团面试:百亿级分片,如何设计基因算法?
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
386 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
算法 前端开发 Java
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
这篇文章总结了单链表的常见面试题,并提供了详细的问题分析、思路分析以及Java代码实现,包括求单链表中有效节点的个数、查找单链表中的倒数第k个节点、单链表的反转以及从尾到头打印单链表等题目。
259 1
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩在读者群中分享了关于分库分表的基因算法设计,旨在帮助大家应对一线互联网企业的面试题。文章详细介绍了分库分表的背景、分片键的设计目标和建议,以及基因法的具体应用和优缺点。通过系统化的梳理,帮助读者提升架构、设计和开发水平,顺利通过面试。
美团面试:百亿级分片,如何设计基因算法?