算法leetcode每日一练2130. 链表最大孪生和
Posted 二当家的白帽子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法leetcode每日一练2130. 链表最大孪生和相关的知识,希望对你有一定的参考价值。
文章目录
- 2130. 链表最大孪生和:
- 样例 1:
- 样例 2:
- 样例 3:
- 提示:
- 分析
- 题解
- 原题传送门:https://leetcode-cn.com/problems/maximum-twin-sum-of-a-linked-list/
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, 1 0 5 10^5 105] 中的 偶数 。
- 1 <= Node.val <= 1 0 5 10^5 105
分析
- 面对这道算法题目,我陷入了沉思。
- 由于孪生节点的定义,相当于是从链表的头尾两端向中间靠拢,或是从中间向头尾两端分散,这就需要两个方向的遍历。
- 但是从尾向头遍历在单向链表中是不可行的。
- 最简单的把法就是将数据放入可以随机访问的数据结构,比如数组,但是这需要额外的内存空间,而且还不一定能换来时间上的缩短。
- 另外一个办法就是把链表的一半做翻转,这样就可以利用双指针,一个从头到中间做遍历,同时一个从中间到尾做遍历。
- 大部分语言都可以一边利用双指针遍历找到中间位置,同时把前半部分的链表翻转,但是rust在实现时,被所有权问题折磨的快疯掉,所以还是选择把找到中间节点和翻转一半链表分开做。
题解
java
/**
* 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)
// 快慢指针找到中间位置,同时将前半部分翻转
ListNode pre = null;
ListNode slow = head;
ListNode fast = head;
while (fast != null)
fast = fast.next.next;
ListNode node = slow;
slow = node.next;
node.next = pre;
pre = node;
// 计算最大孪生和
int ans = 0;
fast = slow;
slow = pre;
while (fast != null)
ans = Math.max(ans, slow.val + fast.val);
slow = slow.next;
fast = fast.next;
return ans;
c
/**
* Definition for singly-linked list.
* struct ListNode
* int val;
* struct ListNode *next;
* ;
*/
int pairSum(struct ListNode* head)
// 快慢指针找到中间位置,同时将前半部分翻转
struct ListNode *pre = NULL;
struct ListNode *slow = head;
struct ListNode *fast = head;
while (fast)
fast = fast->next->next;
struct ListNode *node = slow;
slow = node->next;
node->next = pre;
pre = node;
// 计算最大孪生和
int ans = 0;
fast = slow;
slow = pre;
while (fast)
ans = fmax(ans, slow->val + fast->val);
slow = slow->next;
fast = fast->next;
return ans;
c++
/**
* Definition for singly-linked list.
* struct ListNode
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr)
* ListNode(int x) : val(x), next(nullptr)
* ListNode(int x, ListNode *next) : val(x), next(next)
* ;
*/
class Solution
public:
int pairSum(ListNode* head)
// 快慢指针找到中间位置,同时将前半部分翻转
ListNode *pre = nullptr;
ListNode *slow = head;
ListNode *fast = head;
while (fast)
fast = fast->next->next;
struct ListNode *node = slow;
slow = node->next;
node->next = pre;
pre = node;
// 计算最大孪生和
int ans = 0;
fast = slow;
slow = pre;
while (fast)
ans = max(ans, slow->val + fast->val);
slow = slow->next;
fast = fast->next;
return ans;
;
python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def pairSum(self, head: Optional[ListNode]) -> int:
# 快慢指针找到中间位置,同时将前半部分翻转
pre = None
slow = head
fast = head
while fast:
fast = fast.next.next
node = slow
slow = node.next
node.next = pre
pre = node
# 计算最大孪生和
ans = 0
fast = slow
slow = pre
while fast:
ans = max(ans, slow.val + fast.val)
slow = slow.next
fast = fast.next
return ans
go
/**
* Definition for singly-linked list.
* type ListNode struct
* Val int
* Next *ListNode
*
*/
func pairSum(head *ListNode) int
// 快慢指针找到中间位置,同时将前半部分翻转
var pre *ListNode = nil
slow := head
fast := head
for fast != nil
fast = fast.Next.Next
node := slow
slow = node.Next
node.Next = pre
pre = node
// 计算最大孪生和
ans := 0
fast = slow
slow = pre
for fast != nil
v := slow.Val + fast.Val
if v > ans
ans = v
slow = slow.Next
fast = fast.Next
return ans
rust
// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Clone, Debug)]
// pub struct ListNode
// pub val: i32,
// pub next: Option<Box<ListNode>>
//
//
// impl ListNode
// #[inline]
// fn new(val: i32) -> Self
// ListNode
// next: None,
// val
//
//
//
impl Solution
pub fn pair_sum(mut head: Option<Box<ListNode>>) -> i32
// 快慢指针找到中间位置
let mut mid = 1;
let mut slow = &head;
let mut fast = &(head.as_ref().unwrap().next);
while fast.as_ref().unwrap().next.is_some()
fast = &(fast.as_ref().unwrap().next.as_ref().unwrap().next);
slow = &(slow.as_ref().unwrap().next);
mid += 1;
// 反转链表
let mut prev: Option<Box<ListNode>> = None;
let mut curr = head;
for i in 0..mid
let mut node = curr.unwrap();
curr = node.next;
node.next = prev;
prev = Some(node);
// 计算最大孪生和
let mut ans = 0;
let mut x = &prev;
let mut y = &curr;
while y.is_some()
let v = x.as_ref().unwrap().val + y.as_ref().unwrap().val;
if v > ans
ans = v;
x = &(x.as_ref().unwrap().next);
y = &(y.as_ref().unwrap().next);
ans
原题传送门:https://leetcode-cn.com/problems/maximum-twin-sum-of-a-linked-list/
非常感谢你阅读本文~
欢迎【👍点赞】【⭐收藏】【📝评论】~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~
以上是关于算法leetcode每日一练2130. 链表最大孪生和的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode Algorithm 2130. 链表最大孪生和
LeetCode Algorithm 2130. 链表最大孪生和
LeetCode Algorithm 2130. 链表最大孪生和