力扣(LeetCode) -143 重排連結串列

weixin_34124651發表於2018-12-30

本題考察的是快慢指標和一些連結串列插入刪除等操作

題目描述

給定一個單連結串列 L:L0→L1→…→Ln-1→Ln ,
將其重新排列後變為: L0→Ln→L1→Ln-1→L2→Ln-2→…
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。

示例 1:

給定連結串列 1->2->3->4, 重新排列為 1->4->2->3.

示例 2:

給定連結串列 1->2->3->4->5, 重新排列為 1->5->2->4->3.

題目思考

我們首先使用快慢指標找到連結串列中間的結點,然後把中間結點和他的後驅(.next)斷開,形成兩個前半截和後半截連結串列。我們把後半截連結串列反轉,然後把後半截連結串列的結點依次插入到前半截連結串列中即可。如下圖所示。

5476585-764b9757e44ad407.png
image.png

程式碼

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        if(head==null||head.next==null)
            return ;
        ListNode res=head;
        ListNode fast=head;
        ListNode slow=head;
        while(fast.next!=null&&fast.next.next!=null){  //使用快慢指標找到中間結點
            fast=fast.next.next;
            slow=slow.next;
        }
        ListNode pre=null,cur=slow.next;   //截成兩個連結串列
        slow.next=null;
        while(cur!=null){    //反轉第二個連結串列
            ListNode temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        while(pre!=null){   //將第二個連結串列的結點依次插入第一個連結串列
            ListNode temp1=res.next;
            ListNode temp2=pre.next;
            res.next=pre;
            pre.next=temp1;
            res=temp1;
            pre=temp2;
        }
    }
}

相關文章