LeetCode143——重排链表

我的LeetCode代码仓:https://github.com/617076674/LeetCode

原题链接:https://leetcode-cn.com/problems/reorder-list/description/

题目描述:

LeetCode143——重排链表_第1张图片

知识点:双指针、链表

思路:用快慢双指针遍历链表区分链表的前半部分和后半部分

借鉴LeetCode141——环形链表和LeetCode142——环形链表II中的思路二,我们用快慢双指针遍历链表以区分链表的前半部分和后半部分。参照代码,慢指针cur2移动一步,则快指针cur3移动2步。

以示例1为例(链表中节点个数是偶数个):-1 -> 1 -> 2 -> 3 -> 4,其中-1是我们设立的虚拟头节点,也是cur2和cur3指针的共同起点。当cur3到达4节点时,遍历结束,此时cur2在2节点,其后半部分节点从cur2.next节点开始。

以示例2为例(链表中节点个数是奇数个):-1 -> 1 -> 2 -> 3 -> 4 -> 5,其中-1是我们设立的虚拟头节点,也是cur2和cur3指针的共同起点。当cur3到达4节点时,遍历结束,此时cur2在3节点,其后半部分节点也从cur2.next节点开始。

因此无论链表中节点个数的奇偶性,在cur2和cur3移动结束后,其后半部分节点均是从cur2.next节点开始的。

我们将链表分成两部分,第一部分是cur2.next节点之前的节点,第二部分是cur2.next及其之后的节点。

接下来我们只需反转第二部分节点,关于反转链表的方法,可以参考LeetCode206——反转链表,本题的实现中使用了非递归的方式反转链表。

最后,我们只需根据题意,用两部分节点拼接出我们需要的新链表即可。

时间复杂度是O(n),其中n为链表中的节点个数。空间复杂度是O(1)。

JAVA代码:

public class Solution {
    public void reorderList(ListNode head) {
        //设立虚拟头节点
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        //cur1指向链表头节点
        ListNode cur1 = head;
        //cur2,cur3是快慢双指针,cur2移动一步,cur3移动两步
        ListNode cur2 = dummyHead;
        ListNode cur3 = dummyHead;
        while(cur3 != null && cur3.next != null) {
            cur2 = cur2.next;
            cur3 = cur3.next.next;
        }
        cur2 = cur2.next;
        //寻找cur2的父节点preCur2
        ListNode preCur2 = dummyHead;
        while(preCur2.next != cur2) {
            preCur2 = preCur2.next;
        }
        preCur2.next = null;
        //反转后半段链表
        ListNode newHead = reverseLinkedList(cur2);
        ListNode newCur1 = newHead;
        //组合出新链表
        while(cur1 != null && newCur1 != null) {
            ListNode nextCur1 = cur1.next;
            ListNode nextNewCur1 = newCur1.next;
            cur1.next = newCur1;
            newCur1.next = nextCur1;
            newCur1 = nextNewCur1;
            cur1 = nextCur1;
        }
    }

    private ListNode reverseLinkedList(ListNode head) {
        if(head == null || head.next == null) {
            return head;
        }
        ListNode pre = null;
        ListNode cur = head;
        ListNode next = cur.next;
        while(cur != null) {
            cur.next = pre;
            pre = cur;
            cur = next;
            if(cur != null) {
                next = cur.next;
            }
        }
        return pre;
    }
}

LeetCode解题报告:

LeetCode143——重排链表_第2张图片

 

你可能感兴趣的:(LeetCode题解)