算法修炼之路——【链表】Leetcode24 两两交换链表中的节点

题目描述

给定一单链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是简单的改变节点内部的值,而是需要实际的进行节点交换。

示例:

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

思路分析

这里我们先考虑两个节点间的互换,可以看图1:
在这里插入图片描述
图 1

如图1所示,T1时刻,我们首先考虑对节点[1, 2]进行交换,则需要:

  1. leftP.next指向rightP.next;
  2. rightP.next指向leftP
  3. 更新leftP的前置节点指针;
    这里需要注意的是交换[1, 2]时,还要考虑进节点1前置节点的更新

然后,T2时刻,我们再来看节点对[3, 4], 这里继续罗列:

1.确定节点3的前置节点(此时应为1);
2. leftP.next指向rightP.next;
3. rightP.next指向leftP
4. 更新leftP的前置节点指针;

我们已经发现了问题的规律,即首先确定交换对的前置节点,其次交换并更新下一对的前置节点;之后为前移,重复此过程。

步骤罗列

  1. 初始化两个指针,这里命名为leftP, rightP,为统一规则,设置哨兵节点;
  2. 开始迭代,迭代体内为交换和位移;
  3. 迭代终止条件为两个指针任一为空,返回哨兵节点的下一节点。

解题代码

    public static ListNode solutionWithTwoP(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        //1. init pointers and dummyHead
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode leftP = head;
        ListNode rightP = head.next;

        ListNode currHead = dummyHead;

        //2. iteration
        while (leftP != null && rightP != null) {
            // exchange
            leftP.next = rightP.next;
            rightP.next = leftP;
            currHead.next = rightP;
            
            //update pos of currHead
            currHead = leftP;

            //move forward
            leftP = leftP.next;
            rightP = leftP == null? null : leftP.next; //attention here
        }

        return dummyHead.next;
    }

复杂度分析

时间复杂度:我们对数据仅进行了一次遍历,所以时间复杂度为O(N);
空间复杂度:我们没有借助额外的容器,所以空间复杂度为常量级O(1)。

GitHub源码

完整可运行文件请访问GitHub

发布了47 篇原创文章 · 获赞 55 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/u011106767/article/details/105308158