encorehe学习手册-leetcode-24. 两两交换链表中的节点

88 阅读1分钟

题目

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

 

示例 1:

image.png

输入:head = [1,2,3,4]
输出:[2,1,4,3]

示例 2:

输入:head = []
输出:[]

示例 3:

输入:head = [1]
输出:[1]

提示:

链表中节点的数目在范围 [0, 100] 内 0 <= Node.val <= 100

题解

解题思路

  • 递归

    • 找终止条件:本题终止条件很明显,当递归到链表为空或者链表只剩一个元素的时候,没得交换了,自然就终止了。
    • 找返回值:返回给上一层递归的值应该是已经交换完成后的子链表。
    • 单次的过程:因为递归是重复做一样的事情,所以从宏观上考虑,只用考虑某一步是怎么完成的。我们假设待交换的俩节点分别为head和next,next的应该接受上一级返回的子链表(参考第2步)。就相当于是一个含三个节点的链表交换前两个节点
var reverseBetween = function(head, left, right) {
    var swapPairs = function(head) {
        if (head === null|| head.next === null) {
            return head;
        }
        const newHead = head.next;
        head.next = swapPairs(newHead.next);
        newHead.next = head;
        return newHead;
    };
  • 迭代

    • 找创建哑结点 dummyHead,令 dummyHead.next = head。令 temp 表示当前到达的节点,初始时 temp = dummyHead。每次需要交换 temp 后面的两个节点。

    • 创建哑结点 dummyHead,令 dummyHead.next = head。令 temp 表示当前到达的节点,初始时 temp = dummyHead。每次需要交换 temp 后面的两个节点。

    • 如果 temp 的后面没有节点或者只有一个节点,则没有更多的节点需要交换,因此结束交换。否则,获得 temp 后面的两个节点 node1 和 node2,通过更新节点的指针关系实现两两交换节点。

    • 交换之前的节点关系是 temp -> node1 -> node2,交换之后的节点关系要变成 temp -> node2 -> node1,因此需要进行如下操作。

temp.next = node2
node1.next = node2.next
node2.next = node1

完成上述操作之后,节点关系即变成 temp -> node2 -> node1。再令 temp = node1,对链表中的其余节点进行两两交换,直到全部节点都被两两交换。

两两交换链表中的节点之后,新的链表的头节点是 dummyHead.next,返回新的链表的头节点即可。

    var swapPairs = function(head) {
        const dummyHead = new ListNode(0);
        dummyHead.next = head;
        let temp = dummyHead;
        while (temp.next !== null && temp.next.next !== null) {
            const node1 = temp.next;
            const node2 = temp.next.next;
            temp.next = node2;
            node1.next = node2.next;
            node2.next = node1;
            temp = node1;
        }
        return dummyHead.next;
    };
  • 奇偶法
var swapPairs = function(head) {
    let count  = 1
    //原链的偶数位   指向上一位
    //原链的奇数位,指向 +3 的位置
    let ret = new ListNode(0,head)
    let preNode = ret
    let nextNode = head
    if(!head) return head
    let newHeade = head.next || head
    while(nextNode !== null) {
        let temp = nextNode.next
    if(count %2 === 1) {
        nextNode.next =(nextNode.next && nextNode.next.next && nextNode.next.next.next) || (nextNode.next && nextNode.next.next) || null
    }else {
        nextNode.next = preNode
    }
    preNode = nextNode
    nextNode = temp
    count ++
    }
    return newHeade
};