LeetCode 3165. 不包含相邻元素的子序列的最大和

news2024/11/24 0:17:42

. - 力扣(LeetCode)

题目

给你一个整数数组 nums 和一个二维数组 queries(n\times 2维),其中 queries[i] = [pos_i,x_i]

对于每个查询 i,首先将 nums[pos_i] 设置为 x_i,然后计算查询 i 的答案,该答案为 nums 中 不包含相邻元素 的子序列的 最大 和。

返回所有查询的答案之和。由于最终答案可能非常大,返回其对 10^9+7 取余 的结果。

子序列 是指从另一个数组中删除一些或不删除元素而不改变剩余元素顺序得到的数组。

  • 示例 1:
    • 输入:nums = [3,5,9], queries = [[1,-2],[0,-3]]
    • 输出:21
    • 解释:
      • 执行第 i = 0 个查询,因为queris[0] = [1, -2],即pos_0=1,x_0=-2,修改nums = [3,-2,9],不包含相邻元素的和最大的子序列为[3, 9],这个子序列的和为 3 + 9 = 12
      • 执行第 i=1 个查询后,因为queris[1] = [0, -3],即pos_1=0,x_1=-3,修改nums = [-3,-2,9],不包含相邻元素的和最大的子序列为[9],这个子序列的和为9。
      • 最终返回结果(12+9) \ mod \ (10^7+9) = 21
  • 示例 2:
    • 输入:nums = [0,-1], queries = [[0,-5]]
    • 输出:0
    • 解释:执行第 1 个查询后,nums = [-5,-1],不包含相邻元素的子序列的最大和为 0(选择空子序列)。
  • 提示:
    • 1 <= nums.length <= 5 * 10^4
    • -10^5 <= nums[i] <= 10^5
    • 1 <= queries.length <= 5 * 10^4
    • queries[i] == [pos_i, x_i]
    • 0 <= pos_i <= nums.length - 1
    • -10^5 <= x_i <= 10^5

解题方案

动态规划法

查询过程可以分为两步:

  1. 更新nums, nums[pos_i] = x_i
  2. 计算更新后的nums, 不包含相邻元素的子序列的最大和。
  •  计算数组中不包含相邻运算的子序列的最大和,暴力解法是列举所有的符合条件的子序列,然后取和最大的一个。进阶解法则是用动态规划的方法。动态规划的状态转移方程如下:sum[i]=\left\{\begin{matrix} max(0, arr[0]) & when\ \ i == 0\\ max(arr[1], arr[0]) & when\ \ i == 1\\ max(arr[i-2] + arr[i], arr[i-1]) & when\ \ i\geqslant 2 \end{matrix}\right.
class Solution:
    def maximumSumSubsequence(self, nums: List[int], queries: List[List[int]]) -> int:
        def getMaxSumOfSubsequence(sub_nums: List[int]) -> int:
            """计算不含相邻元素的和最大的子序列"""
            if len(sub_nums) <= 2:
                return max(0, max(sub_nums))
            sum_sequence = [0] * len(sub_nums)
            sum_sequence[0] = max(0, sub_nums[0])
            sum_sequence[1] = max(0 + sub_nums[1], sum_sequence[0])
            for i in range(2, len(sub_nums)):
                sum_sequence[i] = max(sum_sequence[i - 2] + sub_nums[i], sum_sequence[i - 1])
            return max(sum_sequence)

        sum = 0
        for item in queries:
            nums[item[0]] = item[1]
            sum += getMaxSumOfSubsequence(nums)
        return sum % (10**9+7)


            

分析复杂度

记nums长度为m, quiries长度为 n

  • 时间复杂度为O(nm)
  • 空间复杂度为O(m)

线段树

每更新一个元素,就要对整个求和数组sum_sequence进行运算,这里存在着一个优化空间,因此我们考虑建立线段树(这是一种区间查询的树),只更新sum_sequence中跟pos_i相关的元素。

对于了解线段树的同学,可能看到“查询”这个词,就很容易想到线段树了。

线段树的介绍见数据结构之线段树-CSDN博客 

class SegNode:
    def __init__(self) -> None:
        self.v00 = 0 # 不包含两边边界的子数组的最大和
        self.v01 = 0 # 不包含左边界的子数组的最大和(右边界可以包含,也可以不包含)
        self.v10 = 0 # 不包含右边界的子数组的最大和(左边界可以包含,也可以不包含)
        self.v11 = 0 # 两边界都可以包含的子数组的最大和

    def set_value(self, v: int) -> None:
        self.v11 = max(v, 0)
    
    def best(self) -> int:
        return self.v11

class SegTree:
    def __init__(self, nums: List[int]) -> None:
        self.n = len(nums)
        self.nums = nums
        self.nodes = [SegNode() for _ in range(4 * len(nums) + 1)]
        self.build(0, 0, len(nums) - 1)

    def popup(self, index):
        left = 2 * index + 1
        right = 2 * index + 2
        left_node = self.nodes[left]
        right_node = self.nodes[right]
        self.nodes[index].v00  = max(left_node.v01 + right_node.v00, left_node.v00 + right_node.v10)
        self.nodes[index].v01 = max(left_node.v01 + right_node.v01, left_node.v00 + right_node.v11)
        self.nodes[index].v10 = max(left_node.v11 + right_node.v00, left_node.v10 + right_node.v10)
        self.nodes[index].v11 = max(left_node.v11 + right_node.v01, left_node.v10 + right_node.v11)

    def build(self, index, left, right) -> None:
        if left == right:
            self.nodes[index].set_value(self.nums[left])
            return
        mid = (left + right) // 2
        self.build(2 * index + 1, left, mid)
        self.build(2 * index + 2, mid + 1, right)
        self.popup(index)

    def update(self, pos: int, value: int) -> None:
        def internal_update(index: int, left: int, right: int, pos: int, value: int) -> None:
            if left > pos or right < pos:
                return
            if left == right:
                self.nodes[index].set_value(value)
                return
            mid = (left + right) // 2
            internal_update(2 * index + 1, left, mid, pos, value)
            internal_update(2 * index + 2, mid + 1, right, pos, value)
            self.popup(index)
        internal_update(0, 0, len(self.nums) - 1, pos, value)

    def query_action(self, pos, value) -> int:
        self.update(pos, value)
            
        return self.nodes[0].v11


class Solution:
    def maximumSumSubsequence(self, nums: List[int], queries: List[List[int]]) -> int:
        tree = SegTree(nums)
        
        sum = 0
        for query in queries:
            sum += tree.query_action(query[0], query[1])
        return sum % (10**9+7)


            

分析复杂度

记nums数组长度为n, queries长度为m

  • 建树的时间复杂度是O(n),每次查询(更新耗时)时间复杂度是O(logn), 总的时间复杂度为O(n+mlogn)

  • 空间复杂度:线段树存储占用了4n+1的空间,因此空间复杂度是O(n)

看下AI的效果

Em。。。。解法没问题,直接用了线段树。

但是,这是我刚刚用MarsCodeIDE编辑的代码呀,就这么水灵灵的吸收进去了???

不知道MarsCode是做了在线学习,还是有先检索本地的产品策略呀

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于无框力矩电机抱闸实现人形机器人在展会中不依赖悬吊

目录&#xff1a; 1 人形机器人在展会中的悬吊状态 2 人形机器人不能长时间站立的原因 3 基于电机抱闸使人形机器长时间站立 4 人形机器人在实用场景中必须长时间站立、快速进行 “静-动” 互换 5 人形机器人在实用场景中实现 “静-动” 快速互换的抱闸控制思路 6 无框力…

Rust 力扣 - 2090. 半径为 k 的子数组平均值

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 半径为 k 的子数组平均值 等价于 子数组长度为2 * k 1的总和 除于 2 * k 1 我们遍历长度为2 * k 1的窗口&#xff0c;我们只需要记录窗口内的平均值即可 题解代码 impl Solution {pub fn get_averages(num…

哪些远程控制软件能高清畅玩黑神话?

远程控制软件近年来越来越普及&#xff0c;这类软件使用场景广泛&#xff0c;包括远程办公、技术支持、教育等。但其实除了协助远程办公之外&#xff0c;对于游戏玩家来说&#xff0c;远程操控软件还是一款能够让他们即使身处异地也能享受到流畅的游戏体验的好工具。利用远程控…

qt QComboBox详解

QComboBox是一个下拉选择框控件&#xff0c;用于从多个选项中选择一个。通过掌握QComboBox 的用法&#xff0c;你将能够在 Qt 项目中轻松添加和管理组合框组件&#xff0c;实现复杂的数据选择和交互功能。 重要方法 addItem(const QString &text)&#xff1a;将一个项目添…

架构师备考-数据库基础

基本概念 数据&#xff08;Data&#xff09;&#xff1a;是描述事物的符号记录&#xff0c;它具有多种表现形式&#xff0c;可以是文字、图形、图像、声音和语言等。信息&#xff08;information&#xff09;&#xff1a;是现实世界事物的存在方式或状态的反映。信息具有可感知…

【牛客刷题实战】二叉树遍历

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 牛客题目&#xff1a; 二叉树遍历 题目描述 输入描述&#xff1a; 输出描述&#xff1a; 示例1 解题思路 问题理解 算法选择 具体思路 解题要点 完整代码&#xff08;C语言&#xff09; 兄弟们共勉 &#xff01;&…

ESP-HaloPanel:用 ESP32-C2 打造超低成本智能家居面板

项目简介 在生活品质日益提升的今天&#xff0c;智能家居系统已经走进了千家万户&#xff0c;并逐渐成为现代生活的一部份。与此同时&#xff0c;一款设计精致、体积轻盈、操作简便的全屋智能家居控制面板&#xff0c;已经成为众多家庭的新宠。这种高效、直观的智能化的解决方…

西北工业大学Journal of Applied Ecology最新研究进展:野生食草动物破坏了干旱自然保护区的土壤种子库及植被恢复潜力

本文首发于“生态学者”微信公众号&#xff01; 自然保护区&#xff08;protected areas&#xff09;是全球生物保护的重要支柱。其中&#xff0c;植物是生物多样性和生态系统的核心组成部分&#xff0c;是实现生物保护目标的前提和基础。土壤种子库&#xff08;soil seed ban…

Kotlin协程-async分析

概述 本章讲解协程中async&#xff0c;await的原理。前提条件是知道父子协程是如何关联的&#xff0c;可以看这篇协程之间父子关系1-Job如何关联的了解。 这里简单讲一下原理&#xff1a;使用await方法&#xff0c;这是一个挂载方法&#xff0c;协程执行到这里就会挂载&#…

推荐一款功能强大的AI实时变声器:FliFlik Voice Changer

FliFlik VoiCE Changer是一款专注于声音变换与音频处理的创新软件&#xff0c;旨在满足从日常娱乐、游戏直播到播客制作、专业音频编辑的多种应用场景需求。无论是想在游戏中变换声音逗乐队友&#xff0c;还是在播客中塑造个性化的音效&#xff0c;这款软件都能提供灵活而强大的…

LeetCode总结-链表

一、遍历链表 1290.二进制链表转整数 2058.找出临界点之间的最小和最大距离 2181.合并零之间的节点 二、删除节点 问&#xff1a;为什么没有修改 dummy&#xff0c;但 dummy.next 却是新链表的头节点&#xff1f;如果删除了 head&#xff0c;那么最后返回的是不是原链表的头…

Apache Dubbo (RPC框架)

本文参考官方文档&#xff1a;Apache Dubbo 1. Dubbo 简介与核心功能 Apache Dubbo 是一个高性能、轻量级的开源Java RPC框架&#xff0c;用于快速开发高性能的服务。它提供了服务的注册、发现、调用、监控等核心功能&#xff0c;以及负载均衡、流量控制、服务降级等高级功能。…

【Flask】二、Flask 路由机制

目录 什么是路由&#xff1f; Flask中的路由 基本路由 动态路由 路由中的HTTP方法 路由函数返回 在Web开发中&#xff0c;路由是将URL映射到相应的处理函数的过程。Flask是一个轻量级的Web应用框架&#xff0c;提供了简单而强大的路由机制&#xff0c;使得开发者能够轻松…

强势改进!TCN-Transformer时间序列预测

强势改进&#xff01;TCN-Transformer时间序列预测 目录 强势改进&#xff01;TCN-Transformer时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现TCN-Transformer时间序列预测&#xff1b; 2.运行环境为Matlab2023b&#xff1b; 3.单个变量时间序…

六西格玛项目助力,手术机器人零部件国产化稳中求胜——张驰咨询

项目背景 XR-1000型腔镜手术机器人是某头部手术机器人企业推出的高端手术设备&#xff0c;专注于微创手术领域&#xff0c;具有高度的精确性和稳定性。而XR-1000型机器人使用的部分核心零部件长期依赖进口&#xff0c;特别是高精度电机、关节执行机构和视觉系统等&#xff0c;…

C++ 优先算法——复写零(双指针)

目录 题目&#xff1a;复写零 1. 题目解析 2. 算法原理 一. 先找到最后一个“复写”数 处理边界情况 二. 复写操作 3. 代码实现 题目&#xff1a;复写零 1. 题目解析 题目截图&#xff1a; 该题目要求的与移动零相似&#xff0c;都要在一个数组上进行操作&#xff0c;…

掌握DFMEA,让潜在设计缺陷无处遁形!

一个微小的设计缺陷&#xff0c;就可能让一款产品从市场宠儿变成过客。那么&#xff0c;如何在设计初期就精准识别并扼杀这些潜在威胁呢&#xff1f;答案就是——巧妙运用DFMEA&#xff08;设计失效模式与效应分析&#xff09;。本文&#xff0c;天行健企业管理咨询公司将详细阐…

时间序列预测(十)——长短期记忆网络(LSTM)

目录 一、LSTM结构 二、LSTM 核心思想 三、LSTM分步演练 &#xff08;一&#xff09;初始化 1、权重和偏置初始化 2、初始细胞状态和隐藏状态初始化 &#xff08;二&#xff09;前向传播 1、遗忘门计算&#xff08;决定从上一时刻隐状态中丢弃多少信息&#xff09; 2、…

FlaskFastAPIgunicornunicorn并发调用

Flask VS. FastAPI Flask和FastAPI是Python中两种流行的Web框架&#xff0c;它们各自具有不同的特点和适用场景。以下是它们之间的一些主要区别&#xff1a; 1. 框架类型 Flask&#xff1a;Flask是一个轻量级的微框架&#xff0c;适合构建小型到中型的Web应用。它灵活且易于扩展…

安装scrcpy-client模块av模块异常,环境问题解决方案

背景 使用 pip install scrcpy-client命令出现以下报错 performance hint: av\logging.pyx:232:5: Exception check on log_callback will always require the GIL to be acquired. Possible solutions: 1. Declare log_callback as noexcept if you control the definition …