【每日一题】三个无重叠子数组的最大和

news/2024/5/20 5:54:01 标签: 滑动窗口, 数组, 2023-11-19

文章目录

  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
  • 写在最后

Tag

滑动窗口】【数组】【2023-11-19


题目来源

689. 三个无重叠子数组的最大和


题目解读


解题思路

方法一:滑动窗口

单个子数组的最大和

我们先来考虑一个长度为 k 的子数组的最大值与取得最大值时的初始位置。可以使用固定长度的滑动窗口来解决本题。

滑动窗口数组和字符串等问题中常用的一个概念。利用滑动窗口可以去掉重复的运算,从而降低时间复杂度。滑动窗口的 “滑动” 指的是窗口每次向右移动一个位置,那么该窗口内的就会增加原窗口右侧的元素,并且会减少原窗口左端点的元素。

我们从数组 [0, k-1] 区间开始,不断地向右滑动窗口,直至窗口右端点到达数组末尾时停止。统计这一过程中长度为 k 的窗口内元素和 sum1 的最大值(记为 maxSum1)及其对应位置。

实现代码为:

class Solution {
public:
    vector<int> maxSumOfOneSubarray(vector<int> &nums, int k) {
        vector<int> ans;
        int sum1 = 0, maxSum1 = 0;
        for (int i = 0; i < nums.size(); ++i) {
            sum1 += nums[i];
            if (i >= k - 1) {
                if (sum1 > maxSum1) {
                    maxSum1 = sum1;
                    ans = {maxSum1, i - k + 1};
                }
                sum1 -= nums[i - k + 1];
            }
        }
        return ans;
    }
};

两个子数组的最大和

我们可以仿照 单个子数组的最大和 问题的解题方法,使用两个固定长度的滑动窗口来求解 两个子数组的最大和

sum1 为第一个滑动窗口的元素和,该滑动窗口[0, k - 1] 开始,sum2 为第二个滑动窗口的元素和,该滑动窗口[k, 2*k - 1] 开始。我们同时向右滑动这两个窗口,并维护 sum1 的最大值 maxSum1 及其对应位置。每次滑动时,记录当前的 maxSum1sum2 之和。统计这一过程中的 maxSum1 + sum2 的最大值(记作 maxSum12)及其对应位置。

实现代码为:

class Solution {
public:
    vector<int> maxSumOfTwoSubarrays(vector<int> &nums, int k) {
        vector<int> ans;
        int sum1 = 0, maxSum1 = 0, maxSum1Idx = 0;
        int sum2 = 0, maxSum12 = 0;
        for (int i = k; i < nums.size(); ++i) {
            sum1 += nums[i - k];
            sum2 += nums[i];
            if (i >= k * 2 - 1) {
                if (sum1 > maxSum1) {
                    maxSum1 = sum1;
                    maxSum1Idx = i - k * 2 + 1;
                }
                if (maxSum1 + sum2 > maxSum12) {
                    maxSum12 = maxSum1 + sum2;
                    ans = {maxSum1Idx, i - k + 1};
                }
                sum1 -= nums[i - k * 2 + 1];
                sum2 -= nums[i - k + 1];
            }
        }
        return ans;
    }
};

三个子数组的最大和

在本题中,可以使用三个长度为 k滑动窗口。设 sum1 为第一个滑动窗口的元素和,该滑动窗口[0, k - 1] 开始,sum2 为第二个滑动窗口的元素和,该滑动窗口[k, 2*k - 1] 开始,sum3 为第三个滑动窗口的元素和,该滑动窗口[2*k, 3*k - 1] 开始。

我们同时向右滑动这三个窗口,并维护 maxSum12 及其对应位置。每次滑动时,记录当前的 maxSum12sum3 之和。统计这一过程中的 maxSum12 + sum3 的最大值(记作 maxTotal)及其对应位置。

对于题目要求的最小字典序,由于我们是从左向右遍历的,并且仅当元素和超过最大元素和时才修改最大元素和,从而保证求出来的下标列表是字典序最小的。

复杂度分析

class Solution {
public:
    vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
        vector<int> res;
        int sum1 = 0, maxSum1 = 0, maxSum1Idx = 0;
        int sum2 = 0, maxSum12 = 0, maxSum12Idx1 = 0, maxSum12Idx2 = 0;
        int sum3 = 0, maxTotal = 0;
        for (int i = 2 * k; i < nums.size(); ++i) {
            sum1 += nums[i - 2 * k];
            sum2 += nums[i - k];
            sum3 += nums[i];
            if (i >= 3 * k - 1) {
                if (sum1 > maxSum1) {
                    maxSum1 = sum1;
                    maxSum1Idx = i - 3 * k + 1; 
                }
                if (maxSum1 + sum2 > maxSum12) {
                    maxSum12 = maxSum1 + sum2;
                    maxSum12Idx1 = maxSum1Idx;
                    maxSum12Idx2 = i - 2 * k + 1;
                }
                if (maxSum12 + sum3 > maxTotal) {
                    maxTotal = maxSum12 + sum3;
                    res = {maxSum12Idx1, maxSum12Idx2, i - k + 1};
                }
                sum1 -= nums[i - 3 * k + 1];
                sum2 -= nums[i - 2 * k + 1];
                sum3 -= nums[i -  k + 1];
            }
        }
        return res;
    }
};

复杂度分析

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( 1 ) O(1) O(1)


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。


http://www.niftyadmin.cn/n/5195781.html

相关文章

Java学习笔记43——函数式接口

函数式接口 函数式接口函数式接口概述函数式接口作为方法的参数函数式接口作为方法的返回值 常用的函数式接口Supplier接口Comsumer接口Predicate接口Function接口 函数式接口 函数式接口概述 有且仅有一个抽象方法的接口 是lambda表达式的前提 需要注意的是 默认方法不是抽…

向量机SVM代码实现

支持向量机&#xff08;SVM, Support Vector Machines&#xff09;是一种广泛应用于分类、回归、甚至是异常检测的监督学习算法。自从Vapnik和Chervonenkis在1995年首次提出&#xff0c;SVM算法就在机器学习领域赢得了巨大的声誉。这部分因为其基于几何和统计理论的坚实数学基础…

T10 数据增强

文章目录 一、准备环境和数据1.环境2. 数据 二、数据增强&#xff08;增加数据集中样本的多样性&#xff09;三、将增强后的数据添加到模型中四、开始训练五、自定义增强函数六、一些增强函数 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f…

Network(三)动态路由与ACL配置

一 三层交换机 1 三层交换机概述 三层交换二层交换三层转发 2 虚拟接口概述 在三层交换机上配置的VLAN接口为虚拟接口&#xff0c;使用Vlanif&#xff08;VLAN虚拟接口&#xff09;实现VLAN间路由&#xff0c;VLAN接口的引入使得应用更加灵活 三层交换机VLAN间通信的转发…

nodejs+vue实验室上机管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

用户&#xff1a;管理员、教师、学生 基础功能&#xff1a;管理课表、管理机房情况、预约机房预约&#xff1b;权限不同&#xff0c;预约类型不同&#xff0c;教师可选课堂预约和个人&#xff1b;课堂预约。 在实验室上机前&#xff0c;实验室管理员需要对教务处发来的上机课表…

Vue 3 和 Spring Boot 3 的操作流程和执行步骤详解

1.介绍 在本篇博客中&#xff0c;我们将详细介绍Vue 3 和 Spring Boot 3 的操作流程和执行步骤。Vue 3 是一款流行的前端框架&#xff0c;而Spring Boot 3 是一款广泛应用于后端开发的框架。通过结合使用这两个框架&#xff0c;我们可以构建出功能强大的全栈应用。 2.Vue 3 的操…

Spark 平障录

Profile Profile 是最重要的第一环。 利用好 spark UI 和 yarn container log分析业务代码&#xff0c;对其计算代价进行预判建设基准&#xff0c;进行对比&#xff0c;比如application id 进行对比&#xff0c;精确到 job DAG 环节 充分利用 UI Stage 页面 页头 summary&…

Echarts柱状图配置代码详解,含常用图例代码

一、初识柱状图 从echarts官网引入基础的柱状图后&#xff0c;可以看到他有如下的配置项。我们可以改变各个配置项的属性&#xff0c;将图例调整为我们期望的效果。 二、常用配置项 因为引入echarts图例后&#xff0c;改变图例的东西都在option配置项中&#xff0c;所以其他部…