两两交换链表中的节点

186 阅读3分钟

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

leetcode 两两交换链表中的节点

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

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

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

示例 2:

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

示例 3:

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

解题:可以使用循环遍历整个链表,将前后两个节点两两交换。先在head头前创建一个哑节点,在用一个指针temp指向哑节点,然后需要交换的就是temp后面的两个节点,然后循环遍历的结束条件就是temp指针后面没有两个节点的,那就不需要交换了。还需要用node1、node2两个指针指向temp后面两个节点,代表需要交换的两个节点,交换之前的状态是temp->node1->node2->node3,交换过程中需要将temp后面指向node2,然后node1后面指向node2的next(就是node3),然后node2的后面再指向node1,这样就变成temp->node2->node1->node3,最后移动下temp到node1除,继续下次交换node1后面的两个节点(node3,node4...)。

 public ListNode swapPairs(ListNode head) {
        ListNode swapListNode = new ListNode(0, head);
        // temp指向需要交换的两个节点前
        ListNode temp = swapListNode;
        // 两个指针指向需要交换的节点
        ListNode node1;
        ListNode node2;
        // 还有节点 还需要交换
        while (temp.next != null && temp.next.next != null) {
            node1 = temp.next;
            node2 = temp.next.next;
            // 将node2移动到node1前面(temp所指节点)
            temp.next = node2;
            // node1后面就不是node2了,而是node2的后面
            node1.next = node2.next;
            // 将node1移动到node2后面(node2所指节点)
            node2.next = node1;
            // temp指针在移动的下下个节点,以便再交换后面的节点(如果有的话)
            temp = node1;
        }
        return swapListNode.next;
    }

或者使用递归将两个节点两两交换,当链表后面的节点没有两个以上时就结束递归。1.首先当前链表后面如果没有节点,或者只有一个节点,那就直接返回当前链表表示不需要交换了,否则继续交换后面两个节点;2.交换过程中先获取后一个节点head.next(当前链表中的第二个节点);3.再将后一个节点head.next指向一个期待完成交换的链表,这个链表是以后后一个节点head.next.next做为头结点的链表继续递归执行第1步去完成交换的链表。4.然后将交换前的第二个节点指向第一个节点,完成交换。

    public ListNode swapPairs(ListNode head) {
        // 链表后面没有两个节点可以交换了
        if (head == null || head.next == null) {
            return head;
        }
        // 获取到后一个节点
        ListNode swapListNode = head.next;
        // 后一个节点的后面指向后面交换完成的链表节点
        head.next = swapPairs(head.next.next);
        // 后一个节点指向前一个节点 完成交换
        swapListNode.next = head;
        // 返回交换完成的节点
        return swapListNode;
    }