Maximum Twin Sum of a Linked List — Problem & Solution
Maximum Twin Sum of a Linked List solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A medium problem.
Maximum Twin Sum of a Linked List is a medium coding problem on two pointers and stack, asked in Amazon and Microsoft interviews.
- Difficulty: Medium
- Topics: Two Pointers, Stack
- Asked at: Amazon, Microsoft
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
A singly linked list has an even number of nodes n. Counting from 0, node i and node n - 1 - i are called twins for every 0 <= i <= n / 2 - 1: the first node pairs with the last, the second with the second-to-last, and so on. A twin sum is the sum of the values of two twins.
Given the head of such a list, return the largest twin sum.
Example 1
Input: head = [3,8,1,6]
Output: 9
Explanation: The twin pairs are (3, 6) and (8, 1), with sums 9 and 9.
Example 2
Input: head = [4,2,2,3]
Output: 7
Explanation: The twin sums are 4 + 3 = 7 and 2 + 2 = 4; the larger is 7.
Example 3
Input: head = [1,100000]
Output: 100001
Explanation: Two nodes are each other's twin.
Constraints
The number of nodes in the list is an even integer in the range [2, 10^5]1 <= Node.val <= 10^5
Hints for Maximum Twin Sum of a Linked List
Hint 1
Node
ipairs with noden - 1 - i, so the first half is read forwards while the second half is read backwards.Hint 2
Find the start of the second half with a slow/fast pointer race.
Hint 3
Reverse the second half in place; then walk the first half and the reversed second half side by side, adding pairs.
How to solve Maximum Twin Sum of a Linked List
Twins mirror each other around the middle, so if the second half is reversed the twins line up: walking both halves together visits each twin pair once.
Approach
- Move
slowone step andfasttwo steps from the head untilfastruns out;slowis then the first node of the second half (indexn / 2). - Reverse the list starting at
slow; call its new headsecond. - Walk
first = headandsecondtogether untilsecondends, tracking the largestfirst.val + second.val.
Why it works
After reversal the k-th node of the reversed half is original index n - 1 - k, while the k-th node from the head is index k — exactly a twin pair, for every k < n / 2.
Complexity
- Time —
O(n) - Space —
O(1)
Pitfalls
- With an even length, slow lands on index
n / 2when fast becomes null — the start of the second half, not the end of the first. - Copying the values into an array also works in O(n) time but uses O(n) memory; the in-place reversal is what interviewers look for.
Reference solution
Python
from typing import Optional
def pairSum(head: Optional[ListNode]) -> int:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
prev = None # reverse the second half
while slow:
slow.next, prev, slow = prev, slow, slow.next
best = 0
while prev:
best = max(best, head.val + prev.val)
head = head.next
prev = prev.next
return bestJava
public static int pairSum(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; }
ListNode prev = null; // reverse the second half
while (slow != null) { ListNode nx = slow.next; slow.next = prev; prev = slow; slow = nx; }
int best = 0;
for (ListNode a = head, b = prev; b != null; a = a.next, b = b.next) best = Math.max(best, a.val + b.val);
return best;
}C++
int pairSum(ListNode* head) {
ListNode *slow = head, *fast = head;
while (fast && fast->next) { slow = slow->next; fast = fast->next->next; }
ListNode* prev = nullptr; // reverse the second half
while (slow) { ListNode* nx = slow->next; slow->next = prev; prev = slow; slow = nx; }
int best = 0;
for (ListNode *a = head, *b = prev; b; a = a->next, b = b->next) best = max(best, a->val + b->val);
return best;
}JavaScript
var pairSum = function(head) {
var slow = head, fast = head;
while (fast !== null && fast.next !== null) { slow = slow.next; fast = fast.next.next; }
var prev = null; // reverse the second half
while (slow !== null) { var nx = slow.next; slow.next = prev; prev = slow; slow = nx; }
var best = 0;
for (var a = head, b = prev; b !== null; a = a.next, b = b.next) best = Math.max(best, a.val + b.val);
return best;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 165 two pointers problems · the whole catalogue
Learn the technique: Two Pointers Technique · Stack Data Structure