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

题目

给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。

第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。

请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。

你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。

一、代码实现

go 复制代码
func oddEvenList(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }
    odd := head          // 奇数链表的当前尾节点
    even := head.Next    // 偶数链表的当前尾节点
    evenHead := even     // 保存偶数链表的头节点
    
    for even != nil && even.Next != nil {
        // 将下一个奇数节点链接到奇数链表尾部
        odd.Next = even.Next
        odd = odd.Next
        
        // 将下一个偶数节点链接到偶数链表尾部
        even.Next = odd.Next
        even = even.Next
    }
    
    // 将偶数链表接在奇数链表尾部
    odd.Next = evenHead
    return head
}

二、算法分析

1. 核心思路
  • 双指针分离 :使用两个指针 oddeven 分别追踪奇偶链表的尾部节点,通过交替连接实现原地修改
  • 循环复用:在遍历过程中逐步构建奇偶链表,保持原始相对顺序
  • 头节点保留 :通过 evenHead 保存偶数链表头节点,最终合并链表时只需一次指针操作
2. 关键步骤
  1. 初始化指针odd 指向第一个节点(奇头),even 指向第二个节点(偶头)
  2. 交替连接
    • odd 的下一个节点指向 even 的下一个节点(下一个奇数节点)
    • even 的下一个节点指向新 odd 的下一个节点(下一个偶数节点)
  3. 指针推进oddeven 同步后移,继续构建各自的链表
  4. 链表合并 :将偶数链表头 evenHead 接在奇数链表尾部
3. 复杂度
指标 说明
时间复杂度 O(n) 单次遍历,每个节点访问一次
空间复杂度 O(1) 仅需固定数量的指针变量

三、图解示例

四、边界条件与扩展

1. 特殊场景验证
  • 空链表 :直接返回 nil
  • 单节点链表:返回原链表(无需处理)
  • 双节点链表:保持原顺序(奇数在前,偶数在后)
  • 长交替链表 :如 R-D-R-D → 分离后奇偶顺序保持不变
2. 多语言实现
python 复制代码
# Python实现(原地修改)
class Solution:
    def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        odd, even, even_head = head, head.next, head.next
        while even and even.next:
            odd.next = even.next
            odd = odd.next
            even.next = odd.next
            even = even.next
        odd.next = even_head
        return head
java 复制代码
// Java实现(指针同步移动)
class Solution {
    public ListNode oddEvenList(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode odd = head, even = head.next, evenHead = even;
        while (even != null && even.next != null) {
            odd.next = even.next;
            odd = odd.next;
            even.next = odd.next;
            even = even.next;
        }
        odd.next = evenHead;
        return head;
    }
}

五、总结与扩展

1. 核心创新点
  • 链式跳跃 :通过 odd.next = even.next 直接跳过偶数节点,避免多次遍历
  • 数学归纳法证明:奇数节点的下一个节点总是偶数节点的下一个节点,确保正确性
2. 扩展应用
  • 多级分离:扩展为分离模3余数不同的节点(如余0、1、2)
  • 双向链表:修改指针操作逻辑支持双向遍历
  • 环形链表检测:结合快慢指针检测环的存在
3. 工程优化方向
  • 内存预分配:预先计算链表长度优化指针操作
  • 并发安全:添加锁机制支持多线程环境下的链表操作
相关推荐
杨连江2 分钟前
原子级平面限域协同晶核诱导定向生长单层鳞片石墨的研究
算法
MATLAB代码顾问8 分钟前
混合粒子群-模拟退火算法(HPSO-SA)求解作业车间调度问题——附MATLAB代码
算法·matlab·模拟退火算法
Felven12 分钟前
C. Prefix Min and Suffix Max
算法
加农炮手Jinx13 分钟前
LeetCode 26. Remove Duplicates from Sorted Array 题解
算法·leetcode·力扣
加农炮手Jinx13 分钟前
LeetCode 88. Merge Sorted Array 题解
算法·leetcode·力扣
格林威13 分钟前
线阵工业相机:如何计算线阵相机的行频(Line Rate)?公式+实例
开发语言·人工智能·数码相机·算法·计算机视觉·工业相机·线阵相机
yueyue54316 分钟前
透过现象看本质:以fast_lio架构的整套算法的局部避障改为TEB算法为例深度探讨——如何成为一个合格的算法架构师?
算法·架构
梨花爱跨境16 分钟前
红人视频×A10算法:亚马逊转化率与流量闭环实战
算法
阿Y加油吧21 分钟前
二刷 LeetCode:75. 颜色分类 & 31. 下一个排列 复盘笔记
笔记·算法·leetcode
风筝在晴天搁浅22 分钟前
LeetCode 378.有序矩阵中第K小的元素
算法·矩阵