30.两两交换链表中的节点

题目链接

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

解法1 暴力解法

思路

两两交换节点,既然通过链表不好修改,那是不是可以将节点缓存到数组当中。

然后修改它们的顺序,最后再逐一修改 next 指针就好。

代码

js 复制代码
function swapPairs(head: ListNode | null): ListNode | null {
    if (!head) {
        return null;
    }
    if (!head.next) {
        return head;
    }
    let cur = head;
    const nodeList = [];
    while (cur) {
        nodeList.push(cur);
        cur = cur.next;
    }
    
    // 交换数组中链表的顺序
    for (let i = 0; i < nodeList.length && nodeList[i] && nodeList[i + 1]; i = i + 2) {
        const temp = nodeList[i + 1];
        nodeList[i + 1] = nodeList[i];
        nodeList[i] = temp;
    }
    
    // 修改每个节点的 next 指针
    for (let i = 0; i < nodeList.length; i++) {
        nodeList[i].next = i === nodeList.length - 1 ? null : nodeList[i + 1];
    }

    return nodeList[0];
};

时空复杂度

时间复杂度:三次遍历 O(n)

空间复杂度:使用额外数组存储 O(n)

解法2 虚拟头节点+双指针

思路

每当需要交换节点或者删除节点等操作,需要获取当前节点的上一个节点,以便操作 next 指针的时候,就可以考虑引入虚拟头节点。

这一题也是一样,两两交换节点时,需要获取上一个节点来操作指针。于是新建一个 dummyHead 连接到 head

再用 prev 变量指向上一个节点,循环遍历链表,两两交换,所以结束条件是当前节点和下一节点存在。

此时有三个节点 prev => first => second

而最终需要交换成 prev => second => first

交换完之后,指针向前走,此时 prev 需要指向 first,它才是下一个两两交换节点的前一个节点。

代码

js 复制代码
function swapPairs(head: ListNode | null): ListNode | null {
    const dummyHead = new ListNode(-1, head);
    let prev = dummyHead;

    while (head && head.next) {
        const first = head;
        const second = head.next;

        prev.next = second;
        first.next = second.next;
        second.next = first;

        prev = first;
        head = first.next;
    }

    return dummyHead.next;
};

时空复杂度

时间复杂度:1次遍历 O(n)

空间复杂度:常数变量 O(1)

相关推荐
AI视觉网奇1 小时前
Uncaught SyntaxError: Failed to construct ‘RTCPeerConnection‘:
前端·javascript·html
再学一点就睡8 小时前
前端网络实战手册:15个高频工作场景全解析
前端·网络协议
C_心欲无痕8 小时前
有限状态机在前端中的应用
前端·状态模式
C_心欲无痕9 小时前
前端基于 IntersectionObserver 更流畅的懒加载实现
前端
candyTong9 小时前
深入解析:AI 智能体(Agent)是如何解决问题的?
前端·agent·ai编程
柳杉9 小时前
建议收藏 | 2026年AI工具封神榜:从Sora到混元3D,生产力彻底爆发
前端·人工智能·后端
weixin_462446239 小时前
使用 Puppeteer 设置 Cookies 并实现自动化分页操作:前端实战教程
运维·前端·自动化
CheungChunChiu9 小时前
Linux 内核动态打印机制详解
android·linux·服务器·前端·ubuntu
June`10 小时前
全排列与子集算法精解
算法·leetcode·深度优先
GIS之路10 小时前
GDAL 创建矢量图层的两种方式
前端