刷题系列之24. 两两交换链表中的节点

80 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

题目来源

leetcode.cn/problems/sw…

题目介绍

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

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

题目分析

题目意思也比较简单,就是一个链表,要两两交换其中相邻的节点,最后返回头节点。 两两交换,首先肯定是偶数个节点才能两两,如果是奇数个节点,则只用看前面偶数个节点就行。 因此这里肯定需要一个中间节点,方便交换。

核心做法是节点交换后,下一次需要跳过两个节点继续循环;

题目解答

假设head=【1,2,3,4】 这里第一次循环temp相当于是【0,1,2,3,4】。 第二次循环相当于【1,3,4】 最后一次应该为【3】,则不满足了

var swapPairs = function (head) {
  let ret = new ListNode(0, head), temp = ret;//定义一个虚拟的头节点,一个临时节点,用来遍历。
  //判断条件为,如果链表后面还存在2个节点,那么可进行交换
  while (temp.next && temp.next.next) {
      //定义了一个节点cur,等于后面第二个节点。用pre把第一个节点先存起来
    let cur = temp.next.next, pre = temp.next;
    //这里 pre.next相当于temp.next.next,cur.next=temp.next.next.next
    pre.next = cur.next;
    //等同于 让 temp.next.next.next等于temp.next
    cur.next = pre;
    
    temp.next = cur;
    temp = pre;
  }
  return ret.next;
};

image.png

官方答案分析

var swapPairs = function(head) {
    if (head === null|| head.next === null) {//终止条件,必须要有两个节点
        return head;
    }
    const newHead = head.next;//反转后链表的头节点,
    head.next = swapPairs(newHead.next);//让当前递归层的head.next指向交换后返回的头节点
    newHead.next = head;//让反转后的新的头节点指向当前层的head的节点
    return newHead;//返回反转后的头节点
};

用 head 表示原始链表的头节点,新的链表的第二个节点,

用 newHead 表示新的链表的头节点,原始链表的第二个节点,则原始链表中的其余节点的头节点是 newHead.next。

令 head.next = swapPairs(newHead.next),表示将其余节点进行两两交换,交换后的新的头节点为 head 的下一个节点。然后令 newHead.next = head,即完成了所有节点的交换。最后返回新的链表的头节点 newHead。

总结

主要还是要围绕递归的思想来处理链表题目。