You are given an integer array enemyEnergies
denoting the energy values of various enemies.
You are also given an integer currentEnergy
denoting the amount of energy you have initially.
You start with 0 points, and all the enemies are unmarked initially.
You can perform either of the following operations zero or multiple times to gain points:
i
, such that currentEnergy >= enemyEnergies[i]
. By choosing this option:
currentEnergy = currentEnergy - enemyEnergies[i]
.i
. By choosing this option:
currentEnergy = currentEnergy + enemyEnergies[i]
.i
is marked.Return an integer denoting the maximum points you can get in the end by optimally performing operations.
Example 1:
Input: enemyEnergies = [3,2,2], currentEnergy = 2
Output: 3
Explanation:
The following operations can be performed to get 3 points, which is the maximum:
points
increases by 1, and currentEnergy
decreases by 2. So, points = 1
, and currentEnergy = 0
.currentEnergy
increases by 3, and enemy 0 is marked. So, points = 1
, currentEnergy = 3
, and marked enemies = [0]
.points
increases by 1, and currentEnergy
decreases by 2. So, points = 2
, currentEnergy = 1
, and marked enemies = [0]
.currentEnergy
increases by 2, and enemy 2 is marked. So, points = 2
, currentEnergy = 3
, and marked enemies = [0, 2]
.points
increases by 1, and currentEnergy
decreases by 2. So, points = 3
, currentEnergy = 1
, and marked enemies = [0, 2]
.Example 2:
Input: enemyEnergies = [2], currentEnergy = 10
Output: 5
Explanation:
Performing the first operation 5 times on enemy 0 results in the maximum number of points.
Constraints:
1 <= enemyEnergies.length <= 105
1 <= enemyEnergies[i] <= 109
0 <= currentEnergy <= 109
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method involves exploring every possible combination of battle choices to determine the one yielding the maximum points. We essentially simulate every scenario by considering all possible sequences of fighting or skipping enemies. This guarantees that we will find the best possible outcome, albeit inefficiently.
Here's how the algorithm would work step-by-step:
def max_points_after_enemy_battles_brute_force(enemies):
max_points = 0
def calculate_max_points(current_index, current_points):
nonlocal max_points
# When we reach the end, update max points
if current_index == len(enemies):
max_points = max(max_points, current_points)
return
# Option 1: Fight the enemy
# Recursively call with updated index and points
calculate_max_points(current_index + 1, current_points + enemies[current_index])
# Option 2: Skip the enemy
# Recursively call with updated index and same points
calculate_max_points(current_index + 1, current_points)
calculate_max_points(0, 0)
return max_points
We want to maximize points gained by choosing which enemies to battle. The trick is to recognize that we should always battle the weakest enemies first if we can defeat them, maximizing our chances to defeat stronger ones later. We also need to consider the constraint that we must battle consecutively.
Here's how the algorithm would work step-by-step:
def maximum_points_after_enemy_battles(initial_strength, enemies):
maximum_points = 0
number_of_enemies = len(enemies)
for start_index in range(number_of_enemies):
current_strength = initial_strength
current_points = 0
sorted_enemies = sorted(enemies, key=lambda x: x[2])
for i in range(start_index, number_of_enemies):
enemy_attack, enemy_points, strength_loss = sorted_enemies[i]
# Check if current strength is enough to defeat the enemy.
if current_strength > enemy_attack:
current_strength -= enemy_attack
current_points += enemy_points
else:
# If we can't defeat, check penalty. Break inner loop
break
maximum_points = max(maximum_points, current_points)
return maximum_points
Case | How to Handle |
---|---|
enemyStrengths or yourStrengths is null or empty | Return 0 immediately as no battles are possible. |
enemyStrengths and yourStrengths have different lengths | Return 0 as a unit is required for each enemy battle; the problem is ill-defined. |
energy is negative | Treat negative energy as 0, disallowing any battles to occur (return 0). |
All yourStrengths are greater than energy | Return 0, as no battle is possible due to insufficient energy. |
All enemyStrengths are very small, yourStrengths are small, energy is very large | Maximize point collection until energy depletion, handled correctly by optimal selection strategy. |
enemyStrengths and yourStrengths are very large (max int) and energy is very large | Potential integer overflow during point calculation can be avoided by careful type casting to long if using Java/C++ during intermediate calculations. |
Some enemyStrengths are zero | Battling enemies with zero strength results in a no-cost point gain, the optimal strategy should account for this. |
Your unit strengths are highly variable, some very small, some very large | The optimal strategy needs to prioritize smaller strengths to enable more battles which maximizes point accumulation. |