2130-链表最大孪生和

Raphael Liu Lv10

在一个大小为 nn偶数 的链表中,对于 0 <= i <= (n / 2) - 1i ,第 i
个节点(下标从 0 开始)的孪生节点为第 (n-1-i) 个节点 。

  • 比方说,n = 4 那么节点 0 是节点 3 的孪生节点,节点 1 是节点 2 的孪生节点。这是长度为 n = 4 的链表中所有的孪生节点。

孪生和 定义为一个节点和它孪生节点两者值之和。

给你一个长度为偶数的链表的头节点 head ,请你返回链表的 最大孪生和

示例 1:

**输入:** head = [5,4,2,1]
**输出:** 6
**解释:**
节点 0 和节点 1 分别是节点 3 和 2 的孪生节点。孪生和都为 6 。
链表中没有其他孪生节点。
所以,链表的最大孪生和是 6 。

示例 2:

**输入:** head = [4,2,2,3]
**输出:** 7
**解释:**
链表中的孪生节点为:
- 节点 0 是节点 3 的孪生节点,孪生和为 4 + 3 = 7 。
- 节点 1 是节点 2 的孪生节点,孪生和为 2 + 2 = 4 。
所以,最大孪生和为 max(7, 4) = 7 。

示例 3:

**输入:** head = [1,100000]
**输出:** 100001
**解释:**
链表中只有一对孪生节点,孪生和为 1 + 100000 = 100001 。

提示:

  • 链表的节点数目是 [2, 105] 中的 偶数
  • 1 <= Node.val <= 105

方法一:快慢指针 + 反转链表

思路与算法

我们首先使用快满指针找出后一半部分的起始节点。具体地,我们用慢指针 slow 指向 head,快指针 fast 指向 head 的下一个节点。随后,我们每次将 slow 向后移动一个节点,同时 fast 向后移动两个节点。当 fast 到达链表的最后一个节点(即下一个节点是空节点)时:

  • slow 刚好指向链表前一半部分的末尾节点;

  • slow 的下一个节点即为链表后一半部分的起始节点。

随后,我们需要将链表的后一半部分进行反转。如果读者不知道如何实现这一步,可以参考「206. 反转链表」的官方题解 。当链表的后一半部分被反转后,原先我们需要求出的是第 i 个节点和第 n-1-i 的节点的和,此时就变成了求出第 i 个节点和第 i+n/2 个节点的和。

这样一来,我们就可以使用两个指针分别从「链表前一半部分的起始节点」和「链表后一半部分的起始节点」开始遍历。在遍历的过程中,我们计算两个指针指向节点的元素之和,并维护最大值即可。

代码

[sol1-C++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public:
int pairSum(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head->next;
while (fast->next) {
slow = slow->next;
fast = fast->next->next;
}
// 反转链表
ListNode* last = slow->next;
while (last->next) {
ListNode* cur = last->next;
last->next = cur->next;
cur->next = slow->next;
slow->next = cur;
}
int ans = 0;
ListNode* x = head;
ListNode* y = slow->next;
while (y) {
ans = max(ans, x->val + y->val);
x = x->next;
y = y->next;
}
return ans;
}
};
[sol1-Python3]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution:
def pairSum(self, head: Optional[ListNode]) -> int:
slow, fast = head, head.next
while fast.next:
slow = slow.next
fast = fast.next.next

# 反转链表
last = slow.next
while last.next:
cur = last.next
last.next = cur.next
cur.next = slow.next
slow.next = cur

ans = 0
x, y = head, slow.next
while y:
ans = max(ans, x.val + y.val)
x, y = x.next, y.next
return ans

复杂度分析

  • 时间复杂度:O(n)。

  • 空间复杂度:O(1)。

 Comments
On this page
2130-链表最大孪生和