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. 工程优化方向
  • 内存预分配:预先计算链表长度优化指针操作
  • 并发安全:添加锁机制支持多线程环境下的链表操作
相关推荐
格林威1 小时前
常规线扫描镜头有哪些类型?能做什么?
人工智能·深度学习·数码相机·算法·计算机视觉·视觉检测·工业镜头
程序员莫小特3 小时前
老题新解|大整数加法
数据结构·c++·算法
过往入尘土4 小时前
服务端与客户端的简单链接
人工智能·python·算法·pycharm·大模型
zycoder.4 小时前
力扣面试经典150题day1第一题(lc88),第二题(lc27)
算法·leetcode·面试
Dream it possible!4 小时前
LeetCode 面试经典 150_哈希表_存在重复元素 II(46_219_C++_简单)
leetcode·面试·散列表
蒙奇D索大4 小时前
【数据结构】考研数据结构核心考点:二叉排序树(BST)全方位详解与代码实现
数据结构·笔记·学习·考研·算法·改行学it
智驱力人工智能5 小时前
工厂抽烟检测系统 智能化安全管控新方案 加油站吸烟检测技术 吸烟行为智能监测
人工智能·算法·安全·边缘计算·抽烟检测算法·工厂抽烟检测系统·吸烟监测
学学学无无止境5 小时前
组合两个表-力扣
leetcode
程序员爱钓鱼5 小时前
Go语言实战案例——进阶与部署篇:编写Makefile自动构建Go项目
后端·算法·go
_Power_Y6 小时前
Java面试常用算法api速刷
java·算法·面试