3147. Taking Maximum Energy From the Mystic Dungeon
Problem Description
In a mystic dungeon, n
magicians are standing in a line. Each magician has an attribute that gives you energy, which could be negative or positive. After absorbing energy from magician i
, you will be instantly transported to magician (i + k)
. This process is repeated until you reach a point where no further jump (i + k)
is possible.
The task is to choose a starting point and teleport with k
jumps, absorbing all the energy values during the journey. You need to find out the maximum possible energy you can accumulate from such a journey.
Intuition
The intuitive solution to this problem involves backtracking from potential endpoints. We recognize that the journey must end at one of the last k
magicians since any journey must fit into the bounds of the array energy
.
We can approach solving this by starting from potential endpoints in the range [n - k, n)
and working backwards through the array. For each starting point in this range, we iterate backward, adding up the energy values at intervals of k
. During this backward iteration, we keep a running sum of the energy values and check if the current sum is the maximum energy obtained so far. This method optimally utilizes the given teleportation mechanic, ensuring all possible paths starting within the defined range are covered.
Learn more about Prefix Sum patterns.
Solution Approach
The solution employs a combination of enumeration and suffix sum calculation. Here’s a step-by-step breakdown:
-
Initialize Variables:
- Set
ans
to negative infinity (-inf
) to ensure that any calculated sum will be larger initially. - Determine
n
, the length of theenergy
array.
- Set
-
Enumerate Endpoints:
- Iterate over indices in the range
[n - k, n)
, considering each one as a potential endpoint of the journey. The end index is chosen from this range since beginning from any index sooner would require more jumps than possible to reach the end.
- Iterate over indices in the range
-
Calculate Sums Backward:
- For each starting index
i
, initializej
withi
and a cumulative sums
starting at 0. - Perform a backward iteration where, for every
j
, the energy at indexj
is added tos
. - Update
ans
with the maximum of the currents
and the previously calculatedans
. - Decrement
j
byk
for each iteration to simulate the teleport jump backward.
- For each starting index
-
Return Result:
- After evaluating all possible starts in the defined range,
ans
, which holds the maximum energy accumulated through a valid path, is returned.
- After evaluating all possible starts in the defined range,
This approach effectively uses backward enumeration to ensure the most energy is accumulated by leveraging the given teleportation constraints.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's consider a simple case where we have a list of magicians with energy values: [3, -5, 7, 2, 8, -10]
and k = 2
.
Step-by-Step Execution:
-
Initialize Variables:
ans
is set to-inf
initially.n
is calculated as6
(the length of the energy array).
-
Enumerate Endpoints:
- Since
n = 6
andk = 2
, the possible endpoints to consider are indices4
and5
.
- Since
-
Calculate Sums Backward:
Starting at Endpoint
4
:- Initialize
j = 4
and cumulatives = 0
. - Add
energy[4]
(which is8
) tos
, updatings = 8
. - Compare
s
withans
, and since8 > -inf
, updateans = 8
. - Decrement
j
byk
(2), resulting inj = 2
. - Add
energy[2]
(which is7
) tos
, updatings = 15
. - Compare
s
withans
, and since15 > 8
, updateans = 15
. - Decrement
j
byk
again, resulting inj = 0
. - Add
energy[0]
(which is3
) tos
, updatings = 18
. - Compare
s
withans
, and since18 > 15
, updateans = 18
. - Decrement
j
to-2
, which is out of bounds, stopping this backward iteration.
Starting at Endpoint
5
:- Initialize
j = 5
and cumulatives = 0
. - Add
energy[5]
(which is-10
) tos
, updatings = -10
. - Compare
s
withans
, and since18 > -10
,ans
remains18
. - Decrement
j
byk
(2), resulting inj = 3
. - Add
energy[3]
(which is2
) tos
, updatings = -8
. - Compare
s
withans
,ans
remains18
. - Decrement
j
byk
again, resulting inj = 1
. - Add
energy[1]
(which is-5
) tos
, updatings = -13
. - Compare
s
withans
, andans
remains18
. - Decrement
j
to-1
, out of bounds, ending this backward iteration.
- Initialize
-
Return Result:
- Finally, return
ans
, which is18
, as the maximum accumulated energy.
- Finally, return
The algorithm effectively navigates the teleportation constraints to determine that starting at index 4
and teleporting backward to indices 4 -> 2 -> 0
, accumulates the maximum energy 18
.
Solution Implementation
1from typing import List
2import math
3
4class Solution:
5 def maximumEnergy(self, energy: List[int], k: int) -> int:
6 # Initialize the result to negative infinity to ensure any sum will be larger initially
7 ans = -math.inf
8 n = len(energy)
9
10 # Iterate over the last k elements in the energy list
11 for i in range(n - k, n):
12 j, current_sum = i, 0
13
14 # Calculate the sum of elements by stepping backwards by k indices
15 while j >= 0:
16 # Add current energy value to current_sum
17 current_sum += energy[j]
18
19 # Update the maximum energy sum
20 ans = max(ans, current_sum)
21
22 # Move j k steps backwards
23 j -= k
24
25 # Return the maximum sum found
26 return ans
27
1class Solution {
2 public int maximumEnergy(int[] energy, int k) {
3 // Initialize the maximum answer to a very low number.
4 int maxEnergy = Integer.MIN_VALUE;
5 int n = energy.length;
6
7 // Loop over the last 'k' elements of the array.
8 for (int i = n - k; i < n; ++i) {
9 // Start another loop to potentially traverse the array backwards in steps of 'k'.
10 for (int j = i, currentSum = 0; j >= 0; j -= k) {
11 // Add the current energy value to the sum.
12 currentSum += energy[j];
13
14 // Update the maximum energy if the current sum is greater.
15 maxEnergy = Math.max(maxEnergy, currentSum);
16 }
17 }
18
19 // Return the maximum sum found.
20 return maxEnergy;
21 }
22}
23
1class Solution {
2public:
3 int maximumEnergy(vector<int>& energy, int k) {
4 int ans = -(1 << 30); // Initialize answer to a very small number, effectively negative infinity
5 int n = energy.size(); // Get the size of the energy vector
6
7 // Iterate over the last k elements of the vector
8 for (int i = n - k; i < n; ++i) {
9 // For each starting position i, initialize sum s to 0
10 for (int j = i, s = 0; j >= 0; j -= k) {
11 s += energy[j]; // Accumulate the energy values at intervals of k
12 ans = std::max(ans, s); // Update ans with the maximum sum encountered
13 }
14 }
15 return ans; // Return the maximum energy sum found
16 }
17};
18
1// Function to calculate the maximum energy accumulated
2// by jumping back k indices in the energy array.
3function maximumEnergy(energy: number[], k: number): number {
4 const n = energy.length; // The length of the energy array
5 let ans = -Infinity; // Initialize the answer to negative infinity
6
7 // Iterate from the (n-k)th to the last element in the energy array
8 for (let i = n - k; i < n; ++i) {
9 let s = 0; // To store the sum of the selected energies
10
11 // Move from index i backwards in steps of k
12 for (let j = i; j >= 0; j -= k) {
13 s += energy[j]; // Accumulate energy value
14 ans = Math.max(ans, s); // Update the maximum energy sum found
15 }
16 }
17
18 return ans; // Return the maximum energy collected
19}
20
Time and Space Complexity
The time complexity of the code is O(n)
, where n
is the length of the array energy
. For each of the last k
elements, the while
loop iterates backwards in steps of k
, potentially covering every element once.
The space complexity of the code is O(1)
, as it uses a constant amount of extra space regardless of the input size.
Learn more about how to find time and space complexity quickly.
What are the two properties the problem needs to have for dynamic programming to be applicable? (Select 2)
Recommended Readings
Prefix Sum The prefix sum is an incredibly powerful and straightforward technique Its primary goal is to allow for constant time range sum queries on an array What is Prefix Sum The prefix sum of an array at index i is the sum of all numbers from index 0 to i By
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Want a Structured Path to Master System Design Too? Don’t Miss This!