当前位置: 首页 > news >正文

LeetCode 3186.施咒的最大总伤害:动态规划+双指针——O(1)空间(暂未发现其他O(1)空间的题解)

【LetMeFly】3186.施咒的最大总伤害:动态规划+双指针——O(1)空间(暂未发现其他O(1)空间的题解)

力扣题目链接:https://leetcode.cn/problems/maximum-total-damage-with-spell-casting/

一个魔法师有许多不同的咒语。

给你一个数组 power ,其中每个元素表示一个咒语的伤害值,可能会有多个咒语有相同的伤害值。

已知魔法师使用伤害值为 power[i] 的咒语时,他们就 不能 使用伤害为 power[i] - 2 ,power[i] - 1 ,power[i] + 1 或者 power[i] + 2 的咒语。

每个咒语最多只能被使用 一次 。

请你返回这个魔法师可以达到的伤害值之和的 最大值 。

 

示例 1:

输入:power = [1,1,3,4]

输出:6

解释:

可以使用咒语 0,1,3,伤害值分别为 1,1,4,总伤害值为 6 。

示例 2:

输入:power = [7,1,6,6]

输出:13

解释:

可以使用咒语 1,2,3,伤害值分别为 1,6,6,总伤害值为 13 。

 

提示:

  • 1 <= power.length <= 105
  • 1 <= power[i] <= 109

解题方法一:动态规划(O(n)空间)

首先二话不说对power数组来个哈希表统计和排序,得到这样的数组:[<1出现2次>, <3出现1次>, ...]。排序依据是power小的优先。

创建动态规划数组,dp[i+1]表示power[0]到power[i]所能达到的最大总伤害(dp[0]=0,此处power[i]代表排序后)。

这样就有状态转移方程:

dp[i+1]=max⁡(dp[i],dp[j]+thisVal)dp[i+1]=\max(dp[i], dp[j]+thisVal)dp[i+1]=max(dp[i],dp[j]+thisVal)

其中dp[i]dp[i]dp[i]代表不使用当前power,dp[j]dp[j]dp[j]是最后一个满足<power[i]−2\lt power[i]-2<power[i]2的power,thisValthisValthisVal代表使用这个power产生的总能量(thisVal=power[i]×times[i]thisVal=power[i]\times times[i]thisVal=power[i]×times[i])。

现在就剩下最后一个问题了,如何快速得到小于power[i]−2power[i]-2power[i]2的最大power是谁,也就是如何得到j的大小。

双指针即可。每当处理一个新power[i]power[i]power[i]时,当power[j]<power[i]−2power[j]\lt power[i]-2power[j]<power[i]2时不断另j+=1j+=1j+=1即可。

  • 时间复杂度O(nlog⁡n)O(n\log n)O(nlogn),其中n=len(power)n=len(power)n=len(power),时间复杂度的来源主要是排序
  • 空间复杂度O(n)O(n)O(n),空间复杂度的来源主要是动态规划数组

AC代码

C++
/** @LastEditTime: 2025-10-11 18:38:56*/
typedef long long ll;
class Solution {
public:ll maximumTotalDamage(vector<int>& power) {unordered_map<int, int> cnt;for (int t : power) {cnt[t]++;}vector<pair<int, int>> values(cnt.begin(), cnt.end());sort(values.begin(), values.end());vector<ll> dp(values.size() + 1);for (int i = 0, j = 0; i < values.size(); i++) {auto& [value, times] = values[i];while (values[j].first < value - 2) {j++;}dp[i + 1] = max(dp[i], dp[j] + (ll) value * times);}return dp.back();}
};
Python
'''
Author: LetMeFly
Date: 2025-10-11 18:10:29
LastEditors: LetMeFly.xyz
LastEditTime: 2025-10-11 18:46:52
'''
from typing import List
from collections import Counterclass Solution:def maximumTotalDamage(self, power: List[int]) -> int:cnt = Counter(power)values = sorted(cnt)dp = [0] * (len(values) + 1)j = 0for i, val in enumerate(values):while values[j] < val - 2:j += 1dp[i + 1] = max(dp[i], dp[j] + val * cnt[val])return dp[-1]

解题方法二:动态规划(O(1)空间)

不难发现方法一中空间复杂度的来源主要是动态规划数组,并且不难发现动态规划数组只需要利用到最近几个。

这是因为和power[i]冲突的power范围向前看也就有个power[i]−1power[i]-1power[i]1power[i]−2power[i]-2power[i]2,假设power中有这两个值,那么至多也就会用到两个前面的dp值。

所以可以使用数个变量来完成dp数组的原地滚动。

  • 时间复杂度O(nlog⁡n)O(n\log n)O(nlogn),其中n=len(power)n=len(power)n=len(power),时间复杂度的来源主要是排序
  • 空间复杂度O(1)O(1)O(1),相比于方法一,原地滚动大大简化了动态规划数组所需的空间

AC代码

Python
'''
Author: LetMeFly
Date: 2025-10-11 18:10:29
LastEditors: LetMeFly.xyz
LastEditTime: 2025-10-11 19:04:17
'''
from typing import List
from collections import Counterclass Solution:def maximumTotalDamage(self, power: List[int]) -> int:cnt = Counter(power)values = sorted(cnt)dp0 = dp1 = dp2 = 0val1 = val2 = -10for val in values:valSum = val * cnt[val]if val - val2 > 2:  # 无冲突useThis = valSum + dp2elif val - val1 > 2:  # 和val2相差小于2,但和val1不冲突useThis = valSum + dp1else:  # 和val1、val2都冲突(一定不会再和前面的冲突了)useThis = valSum + dp0dp = max(useThis, dp2)dp0, dp1, dp2 = dp1, dp2, dpval1, val2 = val2, valreturn dp2

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源

http://www.dtcms.com/a/470005.html

相关文章:

  • LeetCode 热题 100(持续更新版)
  • 网站开发 jsp开发工具网页设计介绍说明
  • 沈阳网站建站推广湖南网站建设效果
  • 会员体系搭建攻略讲解:从分层运营到提升用户忠诚度
  • Merkle Tree(默克尔树)原理分析
  • Vue3 学习笔记 8:其它 API
  • 库早报|15999元!先临三维发布口袋式3D扫描仪;激光制造与增材制造大会延期;拓竹双项入选《时代》年度发明榜
  • 流量网站建设教程电子商务网站建设php
  • React中Element、Fiber、createElement和Component关系
  • 大语言模型(LLM)是“预制菜”? 从应用到底层原理,在到中央厨房的深度解析
  • 做的好的商城网站南昌网站搭建公司 赣ICP
  • 软件测试资源笔记(4万字,持续更新中)
  • 做外贸网站做成哪种形式好WordPress购物个人中心
  • LeetCode 395 - 至少有 K 个重复字符的最长子串
  • 科技有限公司可以做网站建设吗成都网站网络建设
  • Qt绘制折线图
  • Idea中新建package包,变成了Directory
  • 如何自建淘宝客网站wordpress 知笔墨
  • Python爬虫实战:腾讯控股2024年资产负债分析
  • AI-调查研究-100-具身智能 现代AI方法全解析:强化学习、模仿学习与Transformer在机器人控制中的应用
  • Docker核心技术:深入理解网络模式 ——Host/None/Container 模式与混合云原生架构实践
  • 南通市住房城乡建设局网站磁力蜘蛛种子搜索
  • 解决HTML塌陷的方法
  • sqlite 使用: 03-问题记录:在使用 sqlite3_bind_text 中设置 SQLITE_STATIC 参数时,处理不当造成的字符乱码
  • 网站建设与维护难不难为什么找别人做网站
  • 广州木马网站建设公司医院门户网站建设规划
  • 大模型学习之 深入理解编码器与解码器
  • pyqt 触摸屏监听
  • C++ Primer Plus 第六版 第十三章 编程题
  • 大模型前世今生(十二):Hessian矩阵