Maximum Twin Sum of a Linked List
Pair the i-th node with the (n-1-i)-th node; return the max twin sum using the middle-reverse trick.
4 min read
fast-slow linked-list
Problem#
A linked list has even length n. For each i ∈ [0, n/2), the twin of node i is node n - 1 - i. Return the maximum twin sum.
Examples#
[5,4,2,1]→6(5+1 = 6, 4+2 = 6)[4,2,2,3]→7(4+3, 2+2)
Constraints#
- Even length in
[2, 10^5].
Approach#
Same primitives as palindrome-linked-list: find middle, reverse second half, walk both halves in lockstep summing pairs.
Solution#
class Solution {public: int pairSum(ListNode* head) { ListNode *slow = head, *fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; } ListNode* prev = nullptr; while (slow) { ListNode* nxt = slow->next; slow->next = prev; prev = slow; slow = nxt; } int best = 0; ListNode *a = head, *b = prev; while (b) { best = max(best, a->val + b->val); a = a->next; b = b->next; } return best; }};func pairSum(head *ListNode) int { slow, fast := head, head for fast != nil && fast.Next != nil { slow = slow.Next fast = fast.Next.Next } var prev *ListNode for slow != nil { nxt := slow.Next slow.Next = prev prev = slow slow = nxt } best := 0 a, b := head, prev for b != nil { if a.Val+b.Val > best { best = a.Val + b.Val } a = a.Next b = b.Next } return best}from typing import Optional
class Solution: def pairSum(self, head: Optional[ListNode]) -> int: slow, fast = head, head while fast and fast.next: slow = slow.next fast = fast.next.next prev = None while slow: nxt = slow.next slow.next = prev prev = slow slow = nxt best = 0 a, b = head, prev while b: best = max(best, a.val + b.val) a = a.next b = b.next return bestfunction pairSum(head) { let slow = head, fast = head; while (fast && fast.next) { slow = slow.next; fast = fast.next.next; } let prev = null; while (slow) { const nxt = slow.next; slow.next = prev; prev = slow; slow = nxt; } let best = 0; let a = head, b = prev; while (b) { best = Math.max(best, a.val + b.val); a = a.next; b = b.next; } return best;}class Solution { public 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; while (slow != null) { ListNode nxt = slow.next; slow.next = prev; prev = slow; slow = nxt; } int best = 0; ListNode a = head, b = prev; while (b != null) { best = Math.max(best, a.val + b.val); a = a.next; b = b.next; } return best; }}function pairSum(head: ListNode | null): number { let slow = head, fast = head; while (fast && fast.next) { slow = slow!.next; fast = fast.next.next; } let prev: ListNode | null = null; while (slow) { const nxt: ListNode | null = slow.next; slow.next = prev; prev = slow; slow = nxt; } let best = 0; let a: ListNode | null = head, b: ListNode | null = prev; while (b) { best = Math.max(best, (a as ListNode).val + b.val); a = (a as ListNode).next; b = b.next; } return best;}Editorial#
Even length means the fast/slow split is exact — no middle special case. After reversing the second half, the linked-list version of “pair i with n-1-i” is just “advance two pointers from each end of the new structure”. The pattern compose cleanly.
Complexity#
- Time: O(n).
- Space: O(1).
Concept revision#
Related#