2321. Maximum Score Of Spliced Array
Problem Description
You have two integer arrays nums1
and nums2
, both with the same length n
. You can perform at most one operation where you select a contiguous subarray from one array and swap it with the corresponding subarray from the other array.
Specifically, you choose indices left
and right
(where 0 <= left <= right < n
) and swap:
- Elements from
nums1[left]
tonums1[right]
with - Elements from
nums2[left]
tonums2[right]
For example, with nums1 = [1,2,3,4,5]
and nums2 = [11,12,13,14,15]
, if you choose left = 1
and right = 2
:
nums1
becomes[1,12,13,4,5]
(positions 1 and 2 now have values fromnums2
)nums2
becomes[11,2,3,14,15]
(positions 1 and 2 now have values fromnums1
)
Your goal is to maximize the score, which is defined as the maximum sum between the two arrays after the operation. The score = max(sum(nums1), sum(nums2))
.
You can choose to either:
- Perform the swap operation once to maximize the score
- Not perform any swap at all if it doesn't improve the score
The problem asks you to return the maximum possible score you can achieve.
The solution uses Kadane's algorithm to find the maximum gain from swapping. It calculates the difference array d[i] = nums1[i] - nums2[i]
and finds the maximum subarray sum in this difference array. This represents the maximum gain that can be added to sum(nums2)
by swapping elements from nums1
. The process is repeated in reverse (swapping from nums2
to nums1
) to find the maximum between both possibilities.
Intuition
The key insight is to think about what happens when we swap a subarray. When we swap elements from position left
to right
, we're essentially transferring some elements from nums1
to nums2
and vice versa.
Let's say initially sum(nums1) = S1
and sum(nums2) = S2
. When we swap a subarray, what changes?
For nums2
, we remove its original subarray and add the subarray from nums1
. The change in sum is:
- New sum of
nums2
=S2 - (nums2[left] + ... + nums2[right]) + (nums1[left] + ... + nums1[right])
- This can be rewritten as:
S2 + sum of (nums1[i] - nums2[i])
fori
fromleft
toright
This means the gain for nums2
when swapping is the sum of differences (nums1[i] - nums2[i])
over the swapped range. Similarly, the gain for nums1
would be the sum of (nums2[i] - nums1[i])
.
Now the problem reduces to: find a contiguous subarray where the sum of differences is maximum. This is exactly the classic maximum subarray sum problem!
We create a difference array d[i] = nums1[i] - nums2[i]
. Finding the maximum subarray sum in d
tells us the maximum gain we can add to S2
by swapping. We use Kadane's algorithm for this.
But wait - we could also be trying to maximize nums1
instead of nums2
. So we need to check both directions:
- Maximize
nums2
by finding max subarray sum in(nums1[i] - nums2[i])
- Maximize
nums1
by finding max subarray sum in(nums2[i] - nums1[i])
The final answer is the maximum of these two possibilities, considering we might also choose not to swap at all if it doesn't improve the score.
Learn more about Dynamic Programming patterns.
Solution Approach
The solution implements a helper function f(nums1, nums2)
that finds the maximum gain possible when transferring elements from nums1
to nums2
.
Step 1: Calculate the difference array
d = [a - b for a, b in zip(nums1, nums2)]
This creates an array where d[i] = nums1[i] - nums2[i]
. Each element represents how much we gain in nums2
's sum if we include position i
in our swap.
Step 2: Apply Kadane's Algorithm
t = mx = d[0]
for v in d[1:]:
if t > 0:
t += v
else:
t = v
mx = max(mx, t)
This finds the maximum subarray sum in the difference array:
t
tracks the current subarray sum- If
t > 0
, we extend the current subarray by adding the next elementv
- If
t <= 0
, we start a new subarray from the current elementv
mx
keeps track of the maximum sum seen so far
Step 3: Calculate initial sums
s1, s2 = sum(nums1), sum(nums2)
We compute the original sums of both arrays.
Step 4: Find the maximum score
return max(s2 + f(nums1, nums2), s1 + f(nums2, nums1))
We consider two scenarios:
s2 + f(nums1, nums2)
: Maximum sum ofnums2
after potentially swapping (transferring elements fromnums1
tonums2
)s1 + f(nums2, nums1)
: Maximum sum ofnums1
after potentially swapping (transferring elements fromnums2
tonums1
)
The function returns the maximum of these two values, which represents the best possible score we can achieve with at most one swap operation.
The time complexity is O(n)
where n
is the length of the arrays, and the space complexity is O(n)
for storing the difference array.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example to illustrate the solution approach.
Given:
nums1 = [2, 8, 3, 1]
nums2 = [5, 4, 6, 7]
Step 1: Calculate initial sums
s1 = sum(nums1) = 2 + 8 + 3 + 1 = 14
s2 = sum(nums2) = 5 + 4 + 6 + 7 = 22
- Current maximum score without swapping =
max(14, 22) = 22
Step 2: Try to maximize nums2 by transferring from nums1
Calculate difference array d[i] = nums1[i] - nums2[i]
:
d[0] = 2 - 5 = -3
d[1] = 8 - 4 = 4
d[2] = 3 - 6 = -3
d[3] = 1 - 7 = -6
- Difference array:
[-3, 4, -3, -6]
Apply Kadane's algorithm to find maximum subarray sum:
- Start with
t = mx = -3
- Process
d[1] = 4
: Sincet = -3 < 0
, start new subarray:t = 4
,mx = max(-3, 4) = 4
- Process
d[2] = -3
: Sincet = 4 > 0
, extend:t = 4 + (-3) = 1
,mx = max(4, 1) = 4
- Process
d[3] = -6
: Sincet = 1 > 0
, extend:t = 1 + (-6) = -5
,mx = max(4, -5) = 4
Maximum gain for nums2 = 4
New score if we maximize nums2 = 22 + 4 = 26
This gain of 4 comes from swapping only index 1:
- After swap:
nums1 = [2, 4, 3, 1]
,nums2 = [5, 8, 6, 7]
- New sums:
sum(nums1) = 10
,sum(nums2) = 26
Step 3: Try to maximize nums1 by transferring from nums2
Calculate difference array d[i] = nums2[i] - nums1[i]
:
d[0] = 5 - 2 = 3
d[1] = 4 - 8 = -4
d[2] = 6 - 3 = 3
d[3] = 7 - 1 = 6
- Difference array:
[3, -4, 3, 6]
Apply Kadane's algorithm:
- Start with
t = mx = 3
- Process
d[1] = -4
: Sincet = 3 > 0
, extend:t = 3 + (-4) = -1
,mx = max(3, -1) = 3
- Process
d[2] = 3
: Sincet = -1 < 0
, start new:t = 3
,mx = max(3, 3) = 3
- Process
d[3] = 6
: Sincet = 3 > 0
, extend:t = 3 + 6 = 9
,mx = max(3, 9) = 9
Maximum gain for nums1 = 9
New score if we maximize nums1 = 14 + 9 = 23
This gain of 9 comes from swapping indices 2 to 3:
- After swap:
nums1 = [2, 8, 6, 7]
,nums2 = [5, 4, 3, 1]
- New sums:
sum(nums1) = 23
,sum(nums2) = 13
Step 4: Final answer
- Maximum score =
max(26, 23) = 26
The optimal strategy is to swap index 1, transferring the value 8 from nums1 to nums2, achieving a maximum score of 26.
Solution Implementation
1class Solution:
2 def maximumsSplicedArray(self, nums1: List[int], nums2: List[int]) -> int:
3 def find_max_subarray_sum(arr1: List[int], arr2: List[int]) -> int:
4 """
5 Find the maximum subarray sum of the difference array (arr1 - arr2).
6 Uses Kadane's algorithm to find the maximum sum of a contiguous subarray.
7
8 Args:
9 arr1: First array
10 arr2: Second array
11
12 Returns:
13 Maximum sum of any contiguous subarray in the difference array
14 """
15 # Create difference array where each element is arr1[i] - arr2[i]
16 difference = [a - b for a, b in zip(arr1, arr2)]
17
18 # Initialize current sum and maximum sum with the first element
19 current_sum = max_sum = difference[0]
20
21 # Apply Kadane's algorithm starting from the second element
22 for value in difference[1:]:
23 # If current sum is positive, continue the subarray
24 if current_sum > 0:
25 current_sum += value
26 else:
27 # Otherwise, start a new subarray from current element
28 current_sum = value
29
30 # Update maximum sum found so far
31 max_sum = max(max_sum, current_sum)
32
33 return max_sum
34
35 # Calculate the sum of both arrays
36 sum1, sum2 = sum(nums1), sum(nums2)
37
38 # Two scenarios:
39 # 1. Replace a subarray of nums2 with corresponding subarray from nums1
40 # Result: sum2 + maximum gain from swapping (nums1[i] - nums2[i])
41 # 2. Replace a subarray of nums1 with corresponding subarray from nums2
42 # Result: sum1 + maximum gain from swapping (nums2[i] - nums1[i])
43 return max(
44 sum2 + find_max_subarray_sum(nums1, nums2),
45 sum1 + find_max_subarray_sum(nums2, nums1)
46 )
47
1class Solution {
2 public int maximumsSplicedArray(int[] nums1, int[] nums2) {
3 // Calculate initial sums of both arrays
4 int sum1 = 0;
5 int sum2 = 0;
6 int n = nums1.length;
7
8 for (int i = 0; i < n; i++) {
9 sum1 += nums1[i];
10 sum2 += nums2[i];
11 }
12
13 // Try two scenarios:
14 // 1. Replace a subarray in nums2 with a subarray from nums1 (maximize sum2)
15 // 2. Replace a subarray in nums1 with a subarray from nums2 (maximize sum1)
16 int maxGainForNums2 = findMaxSubarraySum(nums1, nums2);
17 int maxGainForNums1 = findMaxSubarraySum(nums2, nums1);
18
19 return Math.max(sum2 + maxGainForNums2, sum1 + maxGainForNums1);
20 }
21
22 /**
23 * Finds the maximum sum of difference subarray using Kadane's algorithm.
24 * This represents the maximum gain we can achieve by swapping a subarray
25 * from source to target array.
26 *
27 * @param source The array we take elements from
28 * @param target The array we replace elements in
29 * @return Maximum gain achievable by swapping a subarray
30 */
31 private int findMaxSubarraySum(int[] source, int[] target) {
32 // Initialize with the first difference value
33 int currentSum = source[0] - target[0];
34 int maxSum = currentSum;
35
36 // Apply Kadane's algorithm on the difference array
37 for (int i = 1; i < source.length; i++) {
38 int difference = source[i] - target[i];
39
40 // Either extend the current subarray or start a new one
41 if (currentSum > 0) {
42 currentSum += difference;
43 } else {
44 currentSum = difference;
45 }
46
47 // Update the maximum sum found so far
48 maxSum = Math.max(maxSum, currentSum);
49 }
50
51 return maxSum;
52 }
53}
54
1class Solution {
2public:
3 int maximumsSplicedArray(vector<int>& nums1, vector<int>& nums2) {
4 // Calculate the total sum of both arrays
5 int sum1 = 0, sum2 = 0;
6 int n = nums1.size();
7
8 for (int i = 0; i < n; ++i) {
9 sum1 += nums1[i];
10 sum2 += nums2[i];
11 }
12
13 // Try two scenarios:
14 // 1. Maximize nums2's sum by swapping a subarray from nums1 to nums2
15 // 2. Maximize nums1's sum by swapping a subarray from nums2 to nums1
16 int maxSum2 = sum2 + f(nums1, nums2); // sum2 + max gain from nums1
17 int maxSum1 = sum1 + f(nums2, nums1); // sum1 + max gain from nums2
18
19 return max(maxSum2, maxSum1);
20 }
21
22private:
23 // Find the maximum gain when swapping a subarray from source to target
24 // Uses Kadane's algorithm on the difference array (source[i] - target[i])
25 int f(vector<int>& source, vector<int>& target) {
26 // Initialize with the first element's difference
27 int currentSum = source[0] - target[0];
28 int maxGain = currentSum;
29
30 // Apply Kadane's algorithm to find maximum subarray sum of differences
31 for (int i = 1; i < source.size(); ++i) {
32 int difference = source[i] - target[i];
33
34 // Either extend the current subarray or start a new one
35 if (currentSum > 0) {
36 currentSum += difference; // Extend current subarray
37 } else {
38 currentSum = difference; // Start new subarray from current position
39 }
40
41 // Update maximum gain found so far
42 maxGain = max(maxGain, currentSum);
43 }
44
45 return maxGain;
46 }
47};
48
1function maximumsSplicedArray(nums1: number[], nums2: number[]): number {
2 // Calculate the total sum of both arrays
3 let sum1 = 0;
4 let sum2 = 0;
5 const n = nums1.length;
6
7 for (let i = 0; i < n; i++) {
8 sum1 += nums1[i];
9 sum2 += nums2[i];
10 }
11
12 // Try two scenarios:
13 // 1. Maximize nums2's sum by swapping a subarray from nums1 to nums2
14 // 2. Maximize nums1's sum by swapping a subarray from nums2 to nums1
15 const maxSum2 = sum2 + findMaxGain(nums1, nums2); // sum2 + max gain from nums1
16 const maxSum1 = sum1 + findMaxGain(nums2, nums1); // sum1 + max gain from nums2
17
18 return Math.max(maxSum2, maxSum1);
19}
20
21/**
22 * Find the maximum gain when swapping a subarray from source to target
23 * Uses Kadane's algorithm on the difference array (source[i] - target[i])
24 * @param source - The array to take subarray from
25 * @param target - The array to replace subarray in
26 * @returns Maximum gain achievable by swapping
27 */
28function findMaxGain(source: number[], target: number[]): number {
29 // Initialize with the first element's difference
30 let currentSum = source[0] - target[0];
31 let maxGain = currentSum;
32
33 // Apply Kadane's algorithm to find maximum subarray sum of differences
34 for (let i = 1; i < source.length; i++) {
35 const difference = source[i] - target[i];
36
37 // Either extend the current subarray or start a new one
38 if (currentSum > 0) {
39 currentSum += difference; // Extend current subarray
40 } else {
41 currentSum = difference; // Start new subarray from current position
42 }
43
44 // Update maximum gain found so far
45 maxGain = Math.max(maxGain, currentSum);
46 }
47
48 return maxGain;
49}
50
Time and Space Complexity
Time Complexity: O(n)
, where n
is the length of the input arrays.
The algorithm performs the following operations:
- Creating the difference array
d
:O(n)
time usingzip
and list comprehension - Finding the maximum subarray sum in array
d
:O(n)
time with a single pass through the array - Computing
sum(nums1)
andsum(nums2)
:O(n)
time each - Calling function
f
twice:2 * O(n) = O(n)
Overall, all operations are linear, resulting in O(n)
time complexity.
Space Complexity: O(n)
The space usage includes:
- The difference array
d
created in functionf
:O(n)
space - Variables
t
,mx
,s1
,s2
:O(1)
space - The function is called twice, but not recursively, so only one difference array exists at any given time
The dominant factor is the difference array, giving us O(n)
space complexity.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Forgetting to Consider No Swap Scenario
A common mistake is assuming that we must perform a swap operation. However, if all elements in nums1
are smaller than their corresponding elements in nums2
(or vice versa), the maximum subarray sum in the difference array could be negative. In this case, not swapping at all gives a better result.
Pitfall Example:
# Incorrect approach - doesn't handle negative maximum properly
def find_max_subarray_sum(arr1, arr2):
difference = [a - b for a, b in zip(arr1, arr2)]
# ... Kadane's algorithm ...
return max_sum # Could be negative!
# If max_sum is negative, adding it decreases the total
result = sum2 + find_max_subarray_sum(nums1, nums2) # Wrong if max_sum < 0
Solution: The code correctly handles this by using Kadane's algorithm which will return 0 when the best option is to not swap anything (empty subarray). However, to make this more explicit, you could add:
max_sum = max(max_sum, 0) # Ensure we consider "no swap" option
2. Initializing Kadane's Algorithm Incorrectly
Another pitfall is incorrectly initializing the maximum sum to 0 or negative infinity instead of the first element of the difference array.
Pitfall Example:
# Wrong initialization
current_sum = max_sum = 0 # Incorrect - misses single element subarrays
# or
max_sum = float('-inf') # Also problematic for edge cases
Solution:
Always initialize both current_sum
and max_sum
with the first element of the difference array:
current_sum = max_sum = difference[0]
3. Not Considering Both Swap Directions
A critical mistake is only considering swapping from nums1
to nums2
but forgetting that swapping from nums2
to nums1
might yield a better result.
Pitfall Example:
# Only considers one direction
def maximumsSplicedArray(self, nums1, nums2):
sum2 = sum(nums2)
max_gain = find_max_subarray_sum(nums1, nums2)
return sum2 + max_gain # Missing the other direction!
Solution: Always check both directions and return the maximum:
return max(
sum2 + find_max_subarray_sum(nums1, nums2),
sum1 + find_max_subarray_sum(nums2, nums1)
)
4. Edge Case: Arrays with Single Element
When arrays have only one element, the algorithm still works but could be inefficient or unclear.
Pitfall Example:
# Potential issue with single element arrays for value in difference[1:]: # This loop won't execute if len(difference) == 1 # ...
Solution:
The current implementation handles this correctly since when difference[1:]
is empty, the loop doesn't execute and max_sum
remains as difference[0]
, which is the correct answer for single-element arrays.
What is the best way of checking if an element exists in an unsorted array once in terms of time complexity? Select the best that applies.
Recommended Readings
What is Dynamic Programming Prerequisite DFS problems dfs_intro Backtracking problems backtracking Memoization problems memoization_intro Pruning problems backtracking_pruning Dynamic programming is an algorithmic optimization technique that breaks down a complicated problem into smaller overlapping sub problems in a recursive manner and uses solutions to the sub problems to construct a solution
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 assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!