2025-01-18:施咒的最大总伤害。用go语言,一个魔法师掌握了多种不同的咒语,每个咒语对应一个伤害值,这些伤害值存储在数组 power 中,其中可能会有多个咒语具有相同的伤害值。

使用某个特定伤害值为 power[i] 的咒语后,魔法师不能再使用伤害值为 power[i] - 2、power[i] - 1、power[i] + 1 或 power[i] + 2 的任何咒语。此外,每个咒语只能被施放一次。

请你计算并返回魔法师能够实现的最大伤害值总和。

1 <= power.length <= 100000。

1 <= power[i] <= 1000000000。

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

输出:13。

解释:

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

答案2025-01-18:

chatgpt

题目来自leetcode3186。

大体步骤如下:

1.在 main 函数中,定义了输入的 power 数组,然后调用 maximumTotalDamage 函数,并打印最终结果。

2.在 maximumTotalDamage 函数中,首先使用一个 map 统计每种攻击力出现的次数,并将不同的攻击力存储到一个切片中,并进行排序。

3.使用动态规划的方法计算最大伤害值总和。创建一个数组 dp 用于存储计算过程中的最大伤害值总和,然后遍历排序后的攻击力数组。

4.对于每个攻击力,根据规则选择是否使用当前攻击力,并更新最大伤害值总和。

5.最终返回 dp[n+2],即最大伤害值总和。

总的时间复杂度:

  • 统计每种攻击力的出现次数时间复杂度为 O(n)。

  • 将不同的攻击力进行排序的时间复杂度为 O(nlogn)。

  • 最大伤害值总和的动态规划过程时间复杂度为 O(n)。

  • 所以总的时间复杂度为 O(n + nlogn)。

总的额外空间复杂度:

  • 除了 power 数组外,在统计每种攻击力的出现次数、排序和动态规划过程中额外使用的空间为 O(n)。

  • 所以总的额外空间复杂度为 O(n)。

综上,总的时间复杂度为 O(nlogn),总的额外空间复杂度为 O(n)。

Go完整代码如下:

package main

import (
"fmt"
"sort"
) func maximumTotalDamage(power []int) int64 {
// 统计每种攻击力的出现次数
cnt := make(map[int]int)
for _, p := range power {
cnt[p]++
} // 将不同的攻击力存储到一个切片并排序
powers := make([]int, 0, len(cnt))
for p := range cnt {
powers = append(powers, p)
}
sort.Ints(powers) n := len(powers)
// dp数组多开几个空间防止下标越界
dp := make([]int64, n+3) for i := 0; i < n; i++ {
x := powers[i] // 继承不选当前值的情况
dp[i+3] = dp[i+2] // 选择当前值x,并处理不同的跳过情况
if _, ok1 := cnt[x-2]; ok1 && cnt[x-1] > 0 {
dp[i+3] = max(dp[i+3], dp[i]+int64(x)*int64(cnt[x]))
} else if ok1 || cnt[x-1] > 0 {
dp[i+3] = max(dp[i+3], dp[i+1]+int64(x)*int64(cnt[x]))
} else {
dp[i+3] += int64(x) * int64(cnt[x])
}
} return dp[n+2]
} func main() {
power := []int{7, 1, 6, 6}
result := maximumTotalDamage(power)
fmt.Println(result)
}

Rust完整代码如下:

use std::collections::HashMap;

fn maximum_total_damage(power: Vec<i32>) -> i64 {
// 统计每种攻击力的出现次数
let mut cnt = HashMap::new();
for &p in &power {
*cnt.entry(p).or_insert(0) += 1;
} // 将不同的攻击力存储到一个 Vec 中并排序
let mut powers: Vec<i32> = cnt.keys().cloned().collect();
powers.sort(); let n = powers.len();
// dp数组多开几个空间防止下标越界
let mut dp = vec![0; n + 3]; for i in 0..n {
let x = powers[i]; // 继承不选当前值的情况
dp[i + 3] = dp[i + 2]; // 选择当前值 x,并处理不同的跳过情况
if cnt.contains_key(&(x - 2)) && cnt.contains_key(&(x - 1)) {
dp[i + 3] = dp[i + 3].max(dp[i] + x as i64 * cnt[&x] as i64);
} else if cnt.contains_key(&(x - 2)) || cnt.contains_key(&(x - 1)) {
dp[i + 3] = dp[i + 3].max(dp[i + 1] + x as i64 * cnt[&x] as i64);
} else {
dp[i + 3] += x as i64 * cnt[&x] as i64;
}
} dp[n + 2]
} fn main() {
let power = vec![7, 1, 6, 6];
let result = maximum_total_damage(power);
println!("{}", result);
}

C完整代码如下:

#include <stdio.h>
#include <stdlib.h> #define MAX_POWERS 1000 // 假设最大的咒语伤害值不会超过1000 // 比较函数用于 qsort
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
} // 计算最大总伤害
long long maximumTotalDamage(int *power, int size) {
int cnt[MAX_POWERS] = {0}; // 统计每种攻击力的出现次数
for (int i = 0; i < size; i++) {
cnt[power[i]]++;
} int powers[MAX_POWERS];
int n = 0; // 将不同的攻击力存储到数组并排序
for (int i = 0; i < MAX_POWERS; i++) {
if (cnt[i] > 0) {
powers[n++] = i;
}
} // 排序
qsort(powers, n, sizeof(int), compare); long long dp[n + 3]; // dp数组
for (int i = 0; i < n + 3; i++) {
dp[i] = 0; // 初始化
} for (int i = 0; i < n; i++) {
int x = powers[i]; // 继承不选当前值的情况
dp[i + 3] = dp[i + 2]; // 选择当前值x,并处理不同的跳过情况
if (cnt[x - 2] > 0 && cnt[x - 1] > 0) {
dp[i + 3] = dp[i + 3] > dp[i] + (long long)x * cnt[x] ? dp[i + 3] : (dp[i] + (long long)x * cnt[x]);
} else if (cnt[x - 2] > 0 || cnt[x - 1] > 0) {
dp[i + 3] = dp[i + 3] > dp[i + 1] + (long long)x * cnt[x] ? dp[i + 3] : (dp[i + 1] + (long long)x * cnt[x]);
} else {
dp[i + 3] += (long long)x * cnt[x];
}
} return dp[n + 2];
} int main() {
int power[] = {7, 1, 6, 6}; // 示例输入
int size = sizeof(power) / sizeof(power[0]);
long long result = maximumTotalDamage(power, size);
printf("%lld\n", result); // 输出结果
return 0;
}

C++完整代码如下:

#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm> using namespace std; long long maximumTotalDamage(vector<int>& power) {
// 统计每种攻击力的出现次数
unordered_map<int, int> cnt;
for (const auto& p : power) {
cnt[p]++;
} // 将不同的攻击力存储到一个向量中并排序
vector<int> powers;
for (const auto& p : cnt) {
powers.push_back(p.first);
}
sort(powers.begin(), powers.end()); int n = powers.size();
// dp 数组多开几个空间防止下标越界
vector<long long> dp(n + 3, 0); for (int i = 0; i < n; i++) {
int x = powers[i]; // 继承不选当前值的情况
dp[i + 3] = dp[i + 2]; // 选择当前值 x,并处理不同的跳过情况
if (cnt.count(x - 2) && cnt[x - 1] > 0) {
dp[i + 3] = max(dp[i + 3], dp[i] + static_cast<long long>(x) * cnt[x]);
} else if (cnt.count(x - 2) || cnt[x - 1] > 0) {
dp[i + 3] = max(dp[i + 3], dp[i + 1] + static_cast<long long>(x) * cnt[x]);
} else {
dp[i + 3] += static_cast<long long>(x) * cnt[x];
}
} return dp[n + 2];
} int main() {
vector<int> power = {7, 1, 6, 6}; // 示例输入
long long result = maximumTotalDamage(power);
cout << result << endl; // 输出结果
return 0;
}

Python完整代码如下:

# -*-coding:utf-8-*-

from collections import Counter

def maximum_total_damage(power):
# 统计每种攻击力的出现次数
cnt = Counter(power)
# 获取不同的攻击力并排序
powers = sorted(cnt.keys()) n = len(powers)
# dp数组多开几个空间防止下标越界
dp = [0] * (n + 3) for i in range(n):
x = powers[i] # 不选当前值的情况
dp[i + 3] = dp[i + 2] # 选择当前值 x,并处理不同的跳过情况
if (x - 2) in cnt and (x - 1) in cnt:
dp[i + 3] = max(dp[i + 3], dp[i] + x * cnt[x])
elif (x - 2) in cnt or (x - 1) in cnt:
dp[i + 3] = max(dp[i + 3], dp[i + 1] + x * cnt[x])
else:
dp[i + 3] += x * cnt[x] return dp[n + 2] # 示例测试
if __name__ == "__main__":
power = [7, 1, 6, 6]
result = maximum_total_damage(power)
print(result) # 输出结果

Javascript完整代码如下:

function maximumTotalDamage(power) {
// 统计每种攻击力的出现次数
const cnt = {};
for (const p of power) {
cnt[p] = (cnt[p] || 0) + 1; // 计数
} // 将不同的攻击力存储到一个数组并排序
const powers = Object.keys(cnt).map(Number);
powers.sort((a, b) => a - b); const n = powers.length;
// dp数组多开几个空间防止下标越界
const dp = new Array(n + 3).fill(0); for (let i = 0; i < n; i++) {
const x = powers[i]; // 继承不选当前值的情况
dp[i + 3] = dp[i + 2]; // 选择当前值x,并处理不同的跳过情况
if ((x - 2) in cnt && (x - 1) in cnt) {
dp[i + 3] = Math.max(dp[i + 3], dp[i] + x * cnt[x]);
} else if ((x - 2) in cnt || (x - 1) in cnt) {
dp[i + 3] = Math.max(dp[i + 3], dp[i + 1] + x * cnt[x]);
} else {
dp[i + 3] += x * cnt[x];
}
} return dp[n + 2];
} // 示例测试
const power = [7, 1, 6, 6];
const result = maximumTotalDamage(power);
console.log(result); // 输出结果

2025-01-18:施咒的最大总伤害。用go语言,一个魔法师掌握了多种不同的咒语,每个咒语对应一个伤害值,这些伤害值存储在数组 power 中,其中可能会有多个咒语具有相同的伤害值。 使用某个特定伤的更多相关文章

  1. 请给Array本地对象增加一个原型方法,它用于删除数组条目中重复的条目(可能有多个),返回值是一个包含被删除的重复条目的新数组。

    这是牛客网上的一道题~ 题意:遇到重复元素就删除(留下第一个不重复的即可). 解题思路:双循环一遍数组,arr[i] == arr[j] 成立时,删除 arr[j],并将 arr[j] 直接push到 ...

  2. JS删除数组条目中重复的条目

    [腾讯2015春招web前端开发练习卷] 请给Array本地对象增加一个原型方法,它用于删除数组条目中重复的条目(可能有多个),返回值是一个包含被删除的重复条目的新数组. Array.prototyp ...

  3. 19 01 18 dango 模型

    定义属性 Django根据属性的类型确定以下信息: 当前选择的数据库支持字段的类型 渲染管理表单时使用的默认html控件 在管理站点最低限度的验证 django会为表创建自动增长的主键列,每个模型只能 ...

  4. [Effective JavaScript 笔记]第36条:只将实例状态存储在实例对象中

    理解原型对象与其实例之间是一对多的关系,对于实现正确的对象行为很重要.常见的错误是不小心将每个实例的数据存储到了其原型中. 示例 一个实现了树型数据结构的类可能将子节点存储在数组中. 实例状态在原型中 ...

  5. 一个想法(续五):IT联盟创业计划:现阶段进度公示、疑问解答及进行中的计划

    前言: 首先今天是元宵节,先祝大伙元宵节快,单纯的快乐! 然后看看开展中的计划: IT联盟创业计划众筹发起:一个想法(续三):一份IT技术联盟创业计划书,开启众筹创业征程 IT联盟创业计划众筹进度:一 ...

  6. JavaScript中对象数组 根据某个属性值 然后push到新的数组

    原文链接 https://segmentfault.com/q/1010000010075035 将下列对象数组中,工资大于1w的员工,增加到对象数组 WanSalary中 var BaiduUser ...

  7. 将字符串存储到注册表中,长度一定是 strlen(text) + 1

    参考:https://docs.microsoft.com/en-us/windows/desktop/sysinfo/registry-value-types 将字符串存储到注册表中,长度参数一定要 ...

  8. 利用POI工具读取word文档并将数据存储到sqlserver数据库中

    今天实现了利用POI工具读取word文档,并将数据存储到sql数据库中,代码如下: package word; import java.io.File; import java.io.FileInpu ...

  9. [ES6系列-03]ES6中关于参数相关特性详解(参数默认值与参数解构赋值与剩余参数)

    [原创] 码路工人 大家好,这里是码路工人有力量,我是码路工人,你们是力量. 今天总结一下 ES6 中跟参数相关的内容. 欢迎补充斧正.留言交流. 让我们互相学习一起进步. 1. ES6 参数默认值( ...

  10. Js数组对象的属性值升序排序,并指定数组中的某个对象移动到数组的最前面

    需求整理: 本篇文章主要实现的是将一个数组的中对象的属性值通过升序的方式排序,然后能够让程序可以指定对应的数组对象移动到程序的最前面. 数组如下所示: var arrayData= [{name: & ...

随机推荐

  1. Abp源码分析之虚拟文件系统Volo.Abp.VirtualFileSystem

    前言 Volo.Abp.VirtualFileSystem 是ABP(ASP.NET Boilerplate)框架中的一个重要组件,它提供了一种抽象文件系统的方式,使得应用程序可以轻松地访问和管理文件 ...

  2. 数据结构之链表篇(单链表,循环链表,双向链表)C语言版

    1.链表 链表是线性表的一种,由一系列节点(结点)组成,每个节点包含一个数据域和一个指向下一个节点的指针域.链表结构可以克服数组需要预先知道数据大小的缺点,而且插入和删除元素很方便,但是失去数组随机读 ...

  3. CodeForces Round 898 (div 4) H题解析

    CodeForces Round 898 (div 4)H. Mad  City 大致思路    对于有n条边和n个点,说明这个图里面只有一个环 并且两人同时开始和结束移动,所以可以得到当Valeri ...

  4. Nuxt.js 应用中的 webpack:compile 事件钩子

    title: Nuxt.js 应用中的 webpack:compile 事件钩子 date: 2024/11/22 updated: 2024/11/22 author: cmdragon excer ...

  5. Redis究竟为什么这么快?

    Redis为什么这么快? 完全基于内存,数据存在内存中,绝大部分请求是纯粹的内存操作,非常快速,跟传统的磁盘文件数据存储相比,避免了通过磁盘IO读取到内存这部分的开销. 数据结构简单,对数据操作也简单 ...

  6. Postgresql——postgis安装

    PostGIS安装 PostGIS 是一个开源数据库拓展,它为 PostgreSQL 数据库增加了对地理空间数据的支持.PostGIS 使得空间数据的存储.查询和分析变得简单高效. PostGIS 是 ...

  7. git gitignore文件不生效

    配置了 .gitigore 文件不生效,是刚开始将那些过滤的文件加到了版本控制.后续增加的,没有进入到版本控制 解决办法就是从版本控制移除,重新更新下gitignore文件 执行以下命令: 根据情况自 ...

  8. 第一个 milestone:内推 50 人拿到微软 offer!

    就在昨天,我的一位候选人和我说,他已经通过面试,正在 offer 沟通阶段.由此,我达成第一个小里程碑:成功内推 50 人拿到了微软 offer! 内推了多少人? 从 2019 年年初开始内推,到现在 ...

  9. 中电金信新捷报:银行客户资源管理领域No.1

    春暖花开,捷报频传 近日,中电金信 客户关系管理系统(CRM) 接连中标 让我们共同见证这波喜讯 01 中电金信凭借优秀的解决方案和丰富的服务案例经验,成功中标某全国性股份制银行同业CRM实施服务采购 ...

  10. jdk安装-windows和linux

    下载:见此博客https://www.cnblogs.com/zn19961006/p/12857930.html 一.windows安装 1.很简单,运行exe,然后一直下一步 选安装路径. 注意: ...