[路飞]_程序员必刷力扣题: 两两交换链表中的节点

246 阅读2分钟

「这是我参与12月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

两两交换链表中的节点

力扣链接

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例 1:

swap_ex1.jpg

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

示例 2:

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

示例 3:

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

提示:

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

递归

思路

  • 需要处理边界条件:链表节点够两位则交换 不够则直接返回
  • 只处理前两位,然后递归处理head.next.next

我们只需要处理前两个节点,交换next信息,保存head.next到newHead变量中,后续需要返回这个新的头结点

head.next等于递归调处理head的第三个节点起的链表结果

新节点的next指向head就完成了链表节点的交换

最后返回newHead

var swapPairs = function(head) {
    if(!head||!head.nextreturn head
    var newHead = head.next
    head.next = swapPairs(head.next.next)
    newHead.next = head
    return newHead
};

遍历

思路

我们也可以通过遍历的方式来解题

  • 需要处理边界条件:链表节点够两位则交换 不够则直接返回
  • 处理链表的前两个节点,并且将指针指向链表的第三个节点,循环处理后续链表
  • 需要声明一个pre,存处理过的节点的最后一位,也是第三个节点的父节点,用来衔接第三个节点

用newHead来保存新联表的起点,即node.next

这里pre的初始值为null,因为刚开始链表前两个节点反转后不需要衔接到别的地方

循环条件是head&&head.next 都有值,即至少两个和节点才需要反转

用变量node1 node2 next 分别保存head,head.next 以及head.next.next

这里我们只需要交换node1和node2并且衔接next

head重新赋值为next

最后用pre衔接当前的node2节点,并且pre向前移动到node1

最后返回newHead

var swapPairs = function(head) {
    if(!head||!head.nextreturn head
    var pre = null
    var newHead = head.next
    while(head&&head.next){
        var node1 = head
        var node2 = head.next
        var next = head.next.next
        node2.next  = node1
        node1.next = next
        head = next
        if(pre) pre.next = node2
        pre = node1
    }
    return newHead
};