songyy5517 / DataStructures-Algorithms

0 stars 0 forks source link

2130. Maximum Twin Sum of a Linked List #109

Open songyy5517 opened 1 month ago

songyy5517 commented 1 month ago

In a linked list of size n, where n is even, the ith 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.

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.

Intuition Essentially, the problem need to match the symmetric nodes in the linked list. A simple idea is to put all the nodes to a stack and a queue respectively, and then always check the top elements. But this way would take up $O(N)$ space. Another idea is that we can use two pointers to reverse the first half part of the linked list, and then start from the middle, we can always get a pair of twin nodes when looping through the linked list, which only oocupies $O(1)$ space.

songyy5517 commented 1 month ago

Apprach: Reverse the first half of the linked list with Two Pointers

  1. Exception handling;
  2. Define Slow & Fast pointers to control the reverse range, another pointer to help complete the reverse oepration;
  3. Looping through the linked list: Reverse the first half of the linked list;
  4. Start from the middle, iterate through the linked list, and calculatet the maximum twin sum;
  5. Return the maximum sum;

Complexity Analysis

songyy5517 commented 1 month ago
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public int pairSum(ListNode head) {
        // Intuition: Two pointers. Find the middle node and reverse the back half part.
        // 1. Exception handling
        if (head == null)
            return 0;

        // 2. Define two pinters
        ListNode slow = head, fast = head, pre = null;

        // 3. Find the middle node & Reverse the first half part
        while (fast != null){
            fast = fast.next.next;
            ListNode p_next = slow.next;
            slow.next = pre;
            pre = slow;
            slow = p_next;
        }

        // 5. Calculate the max sum
        int max = Integer.MIN_VALUE;
        while (pre != null){
            max = Math.max(max, pre.val + slow.val);
            slow = slow.next;
            pre = pre.next;
        }

        return max;
    }
}
songyy5517 commented 1 month ago

2024/5/28