Skip to content

Commit 0a85066

Browse files
committed
Add solution and test-cases for problem 3186
1 parent f03226b commit 0a85066

File tree

3 files changed

+105
-22
lines changed

3 files changed

+105
-22
lines changed

leetcode/3101-3200/3186.Maximum-Total-Damage-With-Spell-Casting/README.md

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,39 @@
11
# [3186.Maximum Total Damage With Spell Casting][title]
22

3-
> [!WARNING|style:flat]
4-
> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)
5-
63
## Description
4+
A magician has various spells.
5+
6+
You are given an array `power`, where each element represents the damage of a spell. Multiple spells can have the same damage value.
7+
8+
It is a known fact that if a magician decides to cast a spell with a damage of `power[i]`, they **cannot** cast any spell with a damage of `power[i] - 2`, `power[i] - 1`, `power[i] + 1`, or `power[i] + 2`.
9+
10+
Each spell can be cast **only once**.
11+
12+
Return the **maximum** possible total damage that a magician can cast.
713

814
**Example 1:**
915

1016
```
11-
Input: a = "11", b = "1"
12-
Output: "100"
13-
```
17+
Input: power = [1,1,3,4]
1418
15-
## 题意
16-
> ...
19+
Output: 6
1720
18-
## 题解
21+
Explanation:
1922
20-
### 思路1
21-
> ...
22-
Maximum Total Damage With Spell Casting
23-
```go
23+
The maximum possible damage of 6 is produced by casting spells 0, 1, 3 with damage 1, 1, 4.
2424
```
2525

26+
**Example 2:**
27+
28+
```
29+
Input: power = [7,1,6,6]
30+
31+
Output: 13
32+
33+
Explanation:
34+
35+
The maximum possible damage of 13 is produced by casting spells 1, 2, 3 with damage 1, 6, 6.
36+
```
2637

2738
## 结语
2839

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,78 @@
11
package Solution
22

3-
func Solution(x bool) bool {
4-
return x
3+
import "sort"
4+
5+
func Solution(power []int) int64 {
6+
if len(power) == 0 {
7+
return 0
8+
}
9+
10+
// 1. Calculate Total Damage per Value and collect unique damage values.
11+
damageSums := make(map[int]int64)
12+
for _, p := range power {
13+
damageSums[p] += int64(p)
14+
}
15+
16+
// Get all unique damage values and sort them.
17+
var uniqueDamages []int
18+
for d := range damageSums {
19+
uniqueDamages = append(uniqueDamages, d)
20+
}
21+
sort.Ints(uniqueDamages)
22+
23+
M := len(uniqueDamages)
24+
if M == 0 {
25+
return 0
26+
}
27+
28+
// 2. Dynamic Programming Array F.
29+
// F[i] stores the max total damage considering spells with damage
30+
// up to and including uniqueDamages[i].
31+
F := make([]int64, M)
32+
33+
// F[0] Base Case:
34+
F[0] = damageSums[uniqueDamages[0]]
35+
36+
// 3. DP Iteration:
37+
for i := 1; i < M; i++ {
38+
currentDamage := uniqueDamages[i]
39+
D_i := damageSums[currentDamage]
40+
41+
// Option 1: Skip spells of currentDamage.
42+
// Max damage is F[i-1].
43+
skipDamage := F[i-1]
44+
45+
// Option 2: Cast all spells of currentDamage.
46+
// Gain D_i. Must add to the max damage achieved up to damage currentDamage - 3.
47+
48+
// Find the index 'j' of the *largest* unique damage value <= currentDamage - 3.
49+
// We use sort.Search to find the first element > currentDamage - 3, then step back.
50+
51+
target := currentDamage - 3
52+
53+
// Search for the first index 'k' where uniqueDamages[k] > target.
54+
// Since sort.Search is not available for a custom search over a slice
55+
// and we need to find the index for uniqueDamages, we use sort.SearchInts
56+
// which is equivalent to finding the insertion point.
57+
58+
// 'k' is the index of the first element STRICTLY GREATER THAN target.
59+
k := sort.SearchInts(uniqueDamages, target+1)
60+
61+
// The index of the largest element <= target is k-1.
62+
j := k - 1
63+
64+
var prevMaxDamage int64 // Will be 0 if no such spell exists (j < 0).
65+
if j >= 0 {
66+
// prevMaxDamage is the max damage considering spells up to uniqueDamages[j].
67+
prevMaxDamage = F[j]
68+
}
69+
70+
castDamage := D_i + prevMaxDamage
71+
72+
// F[i] = max(Option 1, Option 2)
73+
F[i] = max(skipDamage, castDamage)
74+
}
75+
76+
// The result is the maximum damage considering all unique damage values.
77+
return F[M-1]
578
}

leetcode/3101-3200/3186.Maximum-Total-Damage-With-Spell-Casting/Solution_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ func TestSolution(t *testing.T) {
1010
// 测试用例
1111
cases := []struct {
1212
name string
13-
inputs bool
14-
expect bool
13+
inputs []int
14+
expect int64
1515
}{
16-
{"TestCase", true, true},
17-
{"TestCase", true, true},
18-
{"TestCase", false, false},
16+
{"TestCase1", []int{1, 1, 3, 4}, 6},
17+
{"TestCase2", []int{7, 1, 6, 6}, 13},
1918
}
2019

2120
// 开始测试
@@ -30,10 +29,10 @@ func TestSolution(t *testing.T) {
3029
}
3130
}
3231

33-
// 压力测试
32+
// 压力测试
3433
func BenchmarkSolution(b *testing.B) {
3534
}
3635

37-
// 使用案列
36+
// 使用案列
3837
func ExampleSolution() {
3938
}

0 commit comments

Comments
 (0)