leetcode143 重排链表

82 阅读1分钟

这一道题的思路其实就是把链表后半段,依次插入前半段中,且需要把后半段链表进行反转。

思路一:很容易想到的就是使用栈储存后半段来进行反转,然后再依次从栈取出进行合并。

代码如下:

public void reorderList(ListNode head) {
    ListNode start = head;
    ListNode end = head;
    int count = 0;
    while (end != null){
        end = end.next;
        count++;
    }
    if (count <= 2) return;
    count = count/2+1;
    end = head;
    ListNode record = null;
    while (count != 0){
        count--;
        if (count == 0) record = end;
        end = end.next;
    }
    Deque<ListNode> deque = new LinkedList<>();
    while (end != null){
        deque.addLast(end);
        end = end.next;
    }
    record.next = null;
    while (!deque.isEmpty()){
        ListNode node = deque.removeLast();
        node.next = start.next;
        start.next = node;
        start = start.next.next;
    }

该思路是很容易想到的,但是一般面对链表这种题目,都可以考虑原地算法。

思路二

  • 使用快慢指针进行中点定位。
  • 对后半段链表进行反转。
  • 然后进行两两合并。

代码如下

public void reorderList1(ListNode head) {
    if (head.next == null || head.next.next ==null) return;
    ListNode slow = head;
    ListNode fast = head;
    while (fast.next != null && fast.next.next != null){
        slow = slow.next;
        fast = fast.next.next;
    }
    ListNode pre = null;
    ListNode cur = slow.next;
    slow.next = null;
    ListNode next;
    while (cur != null){
        next = cur.next;
        cur.next = pre;
        pre = cur;
        cur = next;
    }
    slow = head;
    cur = pre;
   while (cur != null){
       next = cur.next;
       cur.next = slow.next;
       slow.next = cur;
       slow = slow.next.next;
       cur = next;
   }

基本上就为这道题的最优解,空间复杂度为O(1)。