In a linked list of size n
, where n
is even, the i
th node (0-indexed) of the linked list is known as the twin of the (n-1-i)
th node, if 0 <= i <= (n / 2) - 1
.
n = 4
, then node 0
is the twin of node 3
, and node 1
is the twin of node 2
. These are the only nodes with twins for n = 4
.The twin sum is defined as the sum of a node and its twin.
Given the head
of a linked list with even length, return the maximum twin sum of the linked list.
Example 1:
Input: head = [5,4,2,1]
Output: 6
Explanation: Nodes 0 and 1 are the twins of nodes 3 and 2, respectively. All have twin sum = 6. There are no other nodes with twins in the linked list. Thus, the maximum twin sum of the linked list is 6.
Example 2:
Input: head = [4,2,2,3]
Output: 7
Explanation: The nodes with twins present in this linked list are: - Node 0 is the twin of node 3 having a twin sum of 4 + 3 = 7. - Node 1 is the twin of node 2 having a twin sum of 2 + 2 = 4. Thus, the maximum twin sum of the linked list is max(7, 4) = 7.
Example 3:
Input: head = [1,100000]
Output: 100001
Explanation: There is only one node with a twin in the linked list having twin sum of 1 + 100000 = 100001.
Constraints:
[2, 10^5]
. (Important Edge Case!)1 <= Node.val <= 10^5
Can you write a function to solve this problem in an efficient manner? What is the time and space complexity of your solution?
One straightforward approach is to iterate through the linked list, store the values in an array, and then calculate the twin sums by comparing elements from the start and end of the array. Finally, find the maximum twin sum.
Algorithm:
max_twin_sum
to 0.i = 0
to n / 2 - 1
:
twin_sum = array[i] + array[n - 1 - i]
.max_twin_sum = max(max_twin_sum, twin_sum)
.max_twin_sum
.Code (Python):
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def pairSum_brute_force(head: ListNode) -> int:
arr = []
curr = head
while curr:
arr.append(curr.val)
curr = curr.next
n = len(arr)
max_sum = 0
for i in range(n // 2):
max_sum = max(max_sum, arr[i] + arr[n - 1 - i])
return max_sum
Time Complexity: O(n) for traversing the linked list and O(n/2) which simplifies to O(n) for calculating twin sums, resulting in O(n) overall.
Space Complexity: O(n) for storing the linked list values in an array.
A more efficient approach involves using a stack to store the values of the first half of the linked list. Then, we can iterate through the second half of the list and calculate the twin sums by pairing each node with the value popped from the stack. This avoids the need for an additional array.
Algorithm:
Code (Python):
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def pairSum(head: ListNode) -> int:
slow, fast = head, head
stack = []
# Traverse the first half of linked list and push into stack
while fast and fast.next:
stack.append(slow.val)
slow = slow.next
fast = fast.next.next
max_sum = 0
# Traverse the second half and compare with stack
while slow:
max_sum = max(max_sum, slow.val + stack.pop())
slow = slow.next
return max_sum
Time Complexity: O(n) for traversing the linked list.
Space Complexity: O(n/2) which simplifies to O(n) for the stack, as it stores roughly half the elements of the linked list.
The optimal solution provides the same O(n) time complexity, but reduces the space complexity from O(n) (for the brute force method) to O(n/2) by utilizing stack which is still O(n). This makes it more space-efficient, particularly for large linked lists.