力扣-链表最大孪生和

思路分析

  1. 找链表中点:用快慢指针(慢指针走 1 步,快指针走 2 步)找到链表的中间节点;
  2. 反转后半段链表:将中点后的后半段链表反转;
  3. 计算孪生和:用两个指针分别从链表头部和反转后的后半段头部出发,依次计算每对孪生节点的和,记录最大值。

代码实现

java 复制代码
/**
* 方法一:快慢指针找到中间节点,反转后半部分链表,遍历两部分节点计算最大和
* @param head
* @return
*/
public int pairSum(ListNode head) {
   // 快慢指针找到中间节点
   ListNode slow = head;
   ListNode fast = head;
   while (fast != null && fast.next != null) {
       slow = slow.next;
       fast = fast.next.next;
   }
   // 反转后半部分链表
   ListNode reverseHead = reverseListNode(slow);
   // 遍历两部分节点计算最大和
   int maxSum = 0;
   while (reverseHead != null) {
       int firstNum = head.val;
       int secondNum = reverseHead.val;
       maxSum = Math.max(maxSum, firstNum + secondNum);
       head = head.next;
       reverseHead = reverseHead.next;
   }
   return maxSum;
}

/**
* @Author Feng
* @Description
* @Date 2026/1/14
* @Param [slow]
* @return main.leetcode75.arr_str.entity.ListNode
**/
private ListNode reverseListNode(ListNode head) {
   // 定义前一个节点为null,当前节点为头节点
   ListNode prev = null;
   ListNode curr = head;
   while (curr != null) {
       ListNode temp = curr.next;
       curr.next = prev;
       prev = curr;
       curr = temp;
   }
   return prev;
}

复杂度分析

  • 空间复杂度 O (1):无需额外存储所有节点值,仅用指针操作;
  • 时间复杂度 O (n):找中点 O (n/2) + 反转后半段 O (n/2) + 计算和 O (n/2),总复杂度 O (n)。

思路分析二

  1. 使用快慢指针找中点:

    • 使用快慢指针技术找到链表的中间节点
    • 慢指针每次移动一步,快指针每次移动两步
    • 当快指针到达末尾时,慢指针正好在链表的中点位置
  2. 利用栈存储前半部分节点值:

    • 创建一个双端队列(用作栈)
    • 从头节点开始遍历到中点之前的所有节点
    • 将这些节点的值依次压入栈中
    • 由于栈是后进先出的数据结构,这样栈顶元素对应的是链表后半部分对称位置的节点
  3. 配对求最大和:

    • 从中点开始遍历后半部分链表
    • 每次从栈中弹出一个值(这对应前半部分对称位置的节点值)
    • 将栈中弹出的值与当前后半部分节点的值相加
    • 更新最大和

代码实现二

java 复制代码
public int pairSum2(ListNode head) {
    // 快慢指针找到中间节点
    ListNode slow = head;
    ListNode fast = head;
    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    // 遍历前半部分节点,将节点值加入栈中
    Deque<Integer> stack = new ArrayDeque<>();
    while (head != slow) {
        stack.push(head.val);
        head = head.next;
    }
    // 遍历后半部分节点,弹出栈顶元素与当前节点值计算最大和
    int maxSum = 0;
    while (slow != null) {
        int firstNum = stack.pop();
        int secondNum = slow.val;
        maxSum = Math.max(maxSum, firstNum + secondNum);
        slow = slow.next;
    }
    return maxSum;
}

复杂度分析

  • 时间复杂度:O(n),只需要遍历链表两次
  • 空间复杂度:O(n/2),只需要额外的空间存储前半部分节点的值
    优势: 不需要修改原链表结构
相关推荐
GreenTea41 分钟前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
fqq32 小时前
力扣刷题前置Java语法
算法·leetcode·职场和发展
半夏微凉半夏殇4 小时前
x11与weston对比,优先选哪个
leetcode·均值算法·eclipse
2501_906565124 小时前
数学之美探究
算法
oier_Asad.Chen4 小时前
【洛谷题解/AcWing题解/OI学习笔记】洛谷P2868【USACO07DEC】Sightseeing Cows G(01分数规划求最大比率)
算法·图论·spfa·二分·负环
leisoo80976 小时前
财报数据怎么排雷本地化Python构建财务异常预警系统
人工智能·python·算法
luj_17688 小时前
塔防牌:策略与卡牌的智慧碰撞
服务器·c语言·开发语言·经验分享·算法
wuyk5558 小时前
3.链表:用指针串联的动态数据结构
c语言·开发语言·数据结构·链表
郝学胜-神的一滴9 小时前
干货版《算法导论》17:二叉树核心原理、遍历逻辑与高阶实操全解
数据结构·c++·python·算法·计算机·编程
爱编程的小新☆9 小时前
【LeetCode】从递归到 Flood Fill:5 道题吃透 DFS 的选择、回溯与标记
java·算法·leetcode·深度优先·回溯·flood fill