【leetcode】24. 两两交换链表中的节点

151 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

一、题目

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

力扣链接

二、思路

这种题目可以通过画图来理解。

image.png

以上是一个链表图,这里使用dummy虚拟节点将1234串联起来。

  • 虚拟节点:因为头节点前方无节点,经常需要特殊化处理head节点,所以引入虚拟节点。
    

通过上面的图,所以我们的思路可以分为两步来解决这个问题。

1.局部调整(交换)

image.png 我们模拟了一下1、2两个节点单次交换的逻辑,一共分为4个步骤

  1. 记录pre和3节点位置,防止断链
    
  2. 将2节点 指向 1节点 
    
  3. 将 1节点 指向 3节点
    
  4. 将 pre节点(指交换位置的1节点之前的节点,本次是dummy)指向2节点
    

最终,四个部分完成了 1、2两个节点的交换。

使用1、2两个节点相邻的两个节点pre节点和3节点记录了一下位置,保证链路不会断链。

2.循环迭代 每次循环前需要确保,本次交换的两个节点存在。

while (one != null && one.next != null)

三、代码

class Solution {

    public ListNode swapPairs(ListNode head) {
        //虚拟节点
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode one = head;
        //1.记录pre的位置
        ListNode pre = dummy;
        while (one != null && one.next != null){
            ListNode two = one.next;
            //1.记录next的位置
            ListNode three = two.next;
            //2.将2节点 指向 1节点 
            two.next = one;
            //3.将 1节点 指向 3节点
            one.next = three;
            //4.将 pre节点指向2节点
            pre.next = two;
            pre = one;
            one = three;
        }
        return dummy.next;
    }
}

四、总结

画图可以让思路变得更清晰,建议做题前可以先把图画出来

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情