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)

相关推荐
在无清风1 小时前
Java实现Redis
前端·windows·bootstrap
_一条咸鱼_3 小时前
Vue 配置模块深度剖析(十一)
前端·javascript·面试
yechaoa3 小时前
Widget开发实践指南
android·前端
前端切图仔0014 小时前
WebSocket 技术详解
前端·网络·websocket·网络协议
JarvanMo4 小时前
关于Flutter架构的小小探讨
前端·flutter
前端开发张小七5 小时前
每日一练:4.有效的括号
前端·python
短尾黑猫5 小时前
[LeetCode 1871] 跳跃游戏 7(Ⅶ)
算法·leetcode
顾林海5 小时前
Flutter 图标和按钮组件
android·开发语言·前端·flutter·面试
雯0609~5 小时前
js:循环查询数组对象中的某一项的值是否为空
开发语言·前端·javascript
杰瑞学AI5 小时前
LeetCode详解之如何一步步优化到最佳解法:27. 移除元素
数据结构·python·算法·leetcode·面试·职场和发展