LeetCode算法题(Go语言实现)_32

题目

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

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

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

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

一、代码实现

go 复制代码
func pairSum(head *ListNode) int {
    // 快慢指针找中点
    slow, fast := head, head
    for fast.Next != nil && fast.Next.Next != nil {
        slow = slow.Next
        fast = fast.Next.Next
    }
    
    // 反转后半部分链表
    var prev *ListNode
    current := slow.Next
    slow.Next = nil // 断开前后半链表
    for current != nil {
        next := current.Next
        current.Next = prev
        prev = current
        current = next
    }
    
    // 计算最大孪生和
    maxSum := 0
    p1, p2 := head, prev
    for p1 != nil && p2 != nil {
        sum := p1.Val + p2.Val
        if sum > maxSum {
            maxSum = sum
        }
        p1 = p1.Next
        p2 = p2.Next
    }
    return maxSum
}

二、算法分析

1. 核心思路
  • 双指针分割:通过快慢指针将链表分为前后两半
  • 链表反转:反转后半部分链表以实现对称访问
  • 并行遍历:同时遍历前半段和反转后的后半段计算孪生和
2. 关键步骤
  1. 快慢指针定位中点:快指针走两步,慢指针走一步,最终慢指针指向前半段末尾
  2. 反转后半链表:采用经典三指针法反转链表,时间复杂度 O(n/2)
  3. 孪生和计算:通过双指针并行遍历,比较每个对称节点对的和值
3. 复杂度
指标 说明
时间复杂度 O(n) 遍历链表三次(分割、反转、求和)
空间复杂度 O(1) 仅使用固定数量的指针变量

三、图解示例

四、边界条件与扩展

1. 特殊场景验证
  • 最小偶长链表:输入链表[1,2] → 输出3(直接首尾相加)
  • 全相同元素:输入链表[5,5,5,5] → 输出10(每对和均为10)
  • 极值分布:输入链表[0,100000] → 输出100000(边界测试)
2. 多语言实现
python 复制代码
# Python实现
class Solution:
    def pairSum(self, head: ListNode) -> int:
        # 快慢指针分割
        slow = fast = head
        while fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
        
        # 反转后半部分
        prev, curr = None, slow.next
        slow.next = None
        while curr:
            next_node = curr.next
            curr.next = prev
            prev, curr = curr, next_node
        
        # 计算最大值
        max_sum = 0
        p1, p2 = head, prev
        while p1 and p2:
            max_sum = max(max_sum, p1.val + p2.val)
            p1, p2 = p1.next, p2.next
        return max_sum
java 复制代码
// Java实现
class Solution {
    public int pairSum(ListNode head) {
        // 快慢指针定位中点
        ListNode slow = head, fast = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        
        // 反转后半链表
        ListNode prev = null, curr = slow.next;
        slow.next = null;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        
        // 遍历求最大值
        int maxSum = 0;
        ListNode p1 = head, p2 = prev;
        while (p1 != null && p2 != null) {
            maxSum = Math.max(maxSum, p1.val + p2.val);
            p1 = p1.next;
            p2 = p2.next;
        }
        return maxSum;
    }
}

五、总结与扩展

1. 核心创新点
  • 三段式处理:将问题分解为链表分割、反转、求和的独立模块
  • 空间优化:通过原地反转避免数组存储,实现O(1)空间复杂度
  • 对称访问机制:利用链表反转实现自然对称遍历
2. 扩展应用
  • 回文链表检测:结合快慢指针与反转操作
  • 环形链表处理:通过快慢指针检测环的存在
  • K个一组反转:将本解法中的反转逻辑扩展为分组处理
3. 工程优化方向
  • 内存预判:根据链表长度选择数组存储或原地反转策略
  • 并发安全:添加原子操作保证多线程环境下的指针安全
  • 缓存优化:利用内存局部性原理优化遍历顺序
相关推荐
数据知道4 分钟前
Go基础:Go语言能用到的常用时间处理
开发语言·后端·golang·go语言
LeaderSheepH6 分钟前
常见的排序算法
数据结构·算法·排序算法
周杰伦_Jay1 小时前
【图文详解】强化学习核心框架、数学基础、分类、应用场景
人工智能·科技·算法·机器学习·计算机视觉·分类·数据挖掘
violet-lz1 小时前
Linux静态库与共享库(动态库)全面详解:从创建到应用
算法
贝塔实验室1 小时前
ADMM 算法的基本概念
算法·数学建模·设计模式·矩阵·动态规划·软件构建·傅立叶分析
235162 小时前
【LeetCode】3. 无重复字符的最长子串
java·后端·算法·leetcode·职场和发展
微笑尅乐2 小时前
神奇的位运算——力扣136.只出现一次的数字
java·算法·leetcode·职场和发展
自信的小螺丝钉3 小时前
Leetcode 155. 最小栈 辅助栈
leetcode·
吃着火锅x唱着歌3 小时前
LeetCode 3105.最长的严格递增或递减子数组
算法·leetcode·职场和发展
小卡皮巴拉3 小时前
【笔试强训】Day1
开发语言·数据结构·c++·算法