[路飞]_leetcode-24-两两交换链表中的节点

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

[题目地址] [B站地址]

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

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

示例 1:

输入: head = [1,2,3,4]
输出: [2,1,4,3]
复制代码

示例 2:

输入: head = []
输出: []
复制代码

示例 3:

输入: head = [1]
输出: [1]
复制代码

提示:

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

进阶: 你能在不修改链表节点值的情况下解决这个问题吗?(也就是说,仅修改节点本身。)

本题其实是 leetcode-25. K 个一组翻转链表 的简化版

扫描二维码关注公众号,回复: 13204143 查看本文章

leetcode-25. K 个一组翻转链表 题解感兴趣的小伙伴可以看我之前这边文章 《leetcode-25-K个一组翻转链表》

本题我们只需要找到两个链表节点,然后将它们位置交换,然后将交换后的头节点连接到结果链表的末尾即可

这里我采用两种方式解决问题

题解1

通过递归的方式完成原链表的两两交换

  1. 首先我们需要一个 swap 函数来完成我们递归的逻辑
  2. 该函数会首先判断剩余待处理链表是否有两个节点,如果没有,则直接返回 head 即可
  3. 首先记录传入链表的第三个节点(可能为空),它是后续待处理链表的头节点
  4. 交换传入链表的 headhead.next,此时head.next交换后链表的头节点
  5. 将后续待处理链表处理完成后返回的头节点连接到head节点之后(因为此时 head 节点为交换后的第二个节点)
  6. 返回本次交换后的头节点即可

代码如下:

// 将传入链表的第一,第二个节点交换,并递归处理后续链表
function swap(head){
  // 如果链表节点数量不够2个,直接返回
  if(head===null || head.next===null) return head;
  // 记录后续链表的头节点
  const nextHead = head.next.next,
  vhead = new ListNode(0);
  // 记录要返回的头节点
  vhead.next = head.next;
  // 交换两个节点
  head.next.next = head;
  // 将后续链表处理后返回的头节点连接到交换后第二个节点的后面
  head.next = swap(nextHead)
  // 返回交换后的头节点
  return vhead.next;
}
var swapPairs = function(head) {
  // 调用swap完成链表节点两两交换
  return swap(head);
};
复制代码

题解2

直接在链表遍历过程中处理

  1. 如果输入链表节点数量不足两个,返回原链表
  2. 当剩余待处理链表中有两个节点的时候,记录第三个节点(为后续待处理链表的头节点)
  3. 交换本次处理的两个节点,并将交换后的头节点连接到结果链表末尾
  4. 更新第一个节点指针为后续待处理链表的头节点
  5. 判断是否有第二个节点,如果有,更新第二个节点指针为第二个节点,否则指向 null
  6. 当链表不足两个的时候,判断第一个节点指针是否指向真实节点,如果是,将它连接在结果链表末尾
  7. 返回结果链表头节点即可

代码如下:

var swapPairs = function(head) {
  // 如果输入链表节点数量不足两个,返回原链表
  if(head===null || head.next===null) return head;
  const vhead = new ListNode(0);
  let pre = vhead,
  tail = head,
  next = head.next;
  // 当剩余链表有两个节点的时候
  while(tail&&next){
    // 记录第三个节点
    const nextHead = next.next;
    // 交换两个节点
    next.next = tail;
    tail.next = null;
    // 将交换后的头节点连接到结果链表末尾
    pre.next = next;
    // 更新指针
    pre = tail;
    tail = nextHead;
    next = tail?tail.next:null;
  }
  // 如果最后tail指针指向真实节点,将其连接到结果链表末尾
  if(tail) pre.next = tail;
  // 返回结果链表头节点
  return vhead.next;
};
复制代码

至此我们就完成了 leetcode-24-两两交换链表中的节点

如有任何问题或建议,欢迎留言讨论!

猜你喜欢

转载自juejin.im/post/7031734271387631629