2130-链表最大孪生和
在一个大小为 n
且 n
为 偶数 的链表中,对于 0 <= i <= (n / 2) - 1
的 i
,第 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 个节点的和。
这样一来,我们就可以使用两个指针分别从「链表前一半部分的起始节点」和「链表后一半部分的起始节点」开始遍历。在遍历的过程中,我们计算两个指针指向节点的元素之和,并维护最大值即可。
代码
1 | class Solution { |
1 | class Solution: |
复杂度分析
时间复杂度:O(n)。
空间复杂度:O(1)。
Comments