02. Maximise String Score
β GFG solution to the Maximise String Score problem: find maximum score by performing valid character jumps using dynamic programming and prefix sum optimization. π
The problem can be found at the following link: π Question Link
π§© Problem Description
You are given a string s, and a list of jumps[][] of size n, where each jumps[i] = [s1, s2] denotes that you are allowed to jump from character s1 to s2 in the forward direction.
Additionally, you are allowed to jump forward from a character to any other occurrence of the same character within the string.
You start at index 0 of the string. After every valid jump from index i to index j, where s[i] = s1 and s[j] = s2, you earn a score equal to the sum of ASCII values of all characters between the jump except for the characters equals s2, i.e.
score(i, j) = sum(ascii(s[k]) for i β€ k < j and s[k] != s[j]).
Determine the maximum score that can be achieved by performing a sequence of valid jumps starting from index 0.
π Examples
Example 1
Input: s = "forgfg", jumps[][] = [['f', 'r'], ['r', 'g']]
Output: 429
Explanation: We can jump from 'f' to 'r' at index 2, this will give a score equals to sum of ASCII value of 'f', 'o' i.e. 213.
Now we can jump from 'r' to 'g' at index 5, this will give a score equals to sum of ASCII value of 'r', 'f' i.e. 216.
Hence maximum total score obtained will be 429.Example 2
π Constraints
$1 \le |s| \le 2 \times 10^5$
$1 \le \text{jumps.size()} \le 676$
There are at least two distinct characters in s.
β
My Approach
The optimal approach uses Dynamic Programming with Prefix Sum Optimization and Precomputed Next Character Positions:
Dynamic Programming + Prefix Sum
Initialize Jump Graph:
Add self-loops for all characters (a-z) to allow jumping to same character.
Build adjacency list storing which characters can be jumped to from each character.
Precompute Next Character Positions:
Create a 2D array
nxt[i][c]storing the next occurrence index of charactercafter positioni.Process string from right to left, maintaining last seen position of each character.
Compute Prefix Sums:
Build prefix sum array of ASCII values for O(1) range sum queries.
pre[i]stores sum of ASCII values from index 0 to i-1.
Dynamic Programming:
dp[i]represents maximum score achievable starting from indexi.Process positions from right to left (n-2 to 0).
For each position, try all valid jumps from current character.
Calculate score:
pre[j] - pre[i + offset] + dp[j], where offset is 1 if jumping to same character.
Return Result:
Maximum score starting from index 0 is stored in
dp[0].
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(n Γ m), where n is the length of the string and m is the average number of valid jumps per character. Each position is processed once, and for each position we iterate through all possible jumps (at most 26 + additional custom jumps). The precomputation of next positions takes O(n Γ 26) = O(n) time.
Expected Auxiliary Space Complexity: O(n + m), where n is used for storing DP array, prefix sum array, and next position matrix (n Γ 26), and m is for storing the jump graph adjacency list. The space is dominated by the O(n Γ 26) matrix for next positions.
π§βπ» Code (C++)
β‘ View Alternative Approaches with Code and Analysis
π 2οΈβ£ HashMap-Based Next Position Lookup
π‘ Algorithm Steps:
Build a map storing all positions of each character in the string.
Use binary search to find the next occurrence of target characters efficiently.
Compute prefix sums for ASCII values to calculate substring scores in O(1).
Apply dynamic programming from end to start, tracking maximum achievable score.
π Complexity Analysis:
Time: β±οΈ O(n Γ m Γ log n) - m is average jumps per character, binary search adds log factor
Auxiliary Space: πΎ O(n) - Maps store character positions
β
Why This Approach?
Cleaner lookup logic using STL containers
Binary search provides efficient next position finding
Easy to understand and maintain
Note: This approach results in Time Limit Exceeded (TLE) for large inputs (fails ~1110/1115 test cases due to time constraints).
π 3οΈβ£ Memoized Recursion with Top-Down DP
π‘ Algorithm Steps:
Build adjacency list for valid character jumps including self-loops.
Precompute all next character indices for fast traversal.
Use recursive function with memoization to explore all paths.
Cache results at each position to avoid redundant calculations.
π Complexity Analysis:
Time: β±οΈ O(n Γ m) - Each state computed once with memoization
Auxiliary Space: πΎ O(n) - Recursion stack and memoization array
β
Why This Approach?
Natural recursive structure matches problem definition
Memoization ensures each state computed only once
Easier to debug and trace execution path
π 4οΈβ£ Space-Optimized Iterative DP
π‘ Algorithm Steps:
Process string in reverse without storing full DP array.
Maintain only necessary state for current computation.
Compute next indices on-the-fly to reduce memory footprint.
Update maximum score incrementally as we process each position.
π Complexity Analysis:
Time: β±οΈ O(nΒ² Γ m) - Linear search for next occurrence
Auxiliary Space: πΎ O(n) - Only DP and prefix sum arrays
β
Why This Approach?
Minimal preprocessing required
Simpler data structures
Good for small input sizes or when memory is constrained
π π Comparison of Approaches
π Approach
β±οΈ Time Complexity
πΎ Space Complexity
β Pros
β οΈ Cons
π·οΈ Precomputed Next Array
π’ O(n Γ m)
π’ O(n)
π Fastest lookup
π§ More preprocessing
π HashMap + Binary Search
π‘ O(n Γ m Γ log n)
π’ O(n)
π Clean code structure
π Slower than direct array
π Top-Down Recursion
π’ O(n Γ m)
π‘ O(n)
π― Natural problem flow
πΎ Recursion stack overhead
π Space-Optimized
π΄ O(nΒ² Γ m)
π’ O(n)
β Minimal preprocessing
π Slower time complexity
π Best Choice Recommendation
π― Scenario
ποΈ Recommended Approach
π₯ Performance Rating
π Optimal performance needed
π₯ Precomputed Next Array
β β β β β
π Code clarity priority
π₯ HashMap + Binary Search
β β β β β
π§ Easy debugging needed
π₯ Top-Down Recursion
β β β β β
π― Memory constrained
π Space-Optimized
β β β ββ
β Code (Java)
π Code (Python)
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated