算法leetcode每日一练2130. 链表最大孪生和

Posted 二当家的白帽子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法leetcode每日一练2130. 链表最大孪生和相关的知识,希望对你有一定的参考价值。


文章目录


2130. 链表最大孪生和:

在一个大小为 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, 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. 链表最大孪生和

算法leetcode每日一练1614. 括号的最大嵌套深度

算法leetcode每日一练1725. 可以形成最大正方形的矩形数目

算法leetcode每日一练1614. 括号的最大嵌套深度