【LeetCode】143. 重排鏈表

題目描述

題目原鏈接:重排鏈表
給定一個單鏈表 L:L0→L1→…→Ln-1→Ln ,
將其重新排列後變爲: L0→Ln→L1→Ln-1→L2→Ln-2→…

你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。

示例 1:

給定鏈表 1->2->3->4, 重新排列爲 1->4->2->3.

解釋: 因爲無重複字符的最長子串是 “abc”,所以其長度爲 3。
示例 2:

給定鏈表 1->2->3->4->5, 重新排列爲 1->5->2->4->3.

解答思路

這道題目是我在字節跳動2019年秋招提前批中遇到的,當時寫不出來,所以現在想在這裏總結一下該題的解決思路。
流程:

  1. 把鏈表先拆分爲兩半;(使用快慢指針
  2. 對鏈表的後半段進行反轉的操作;(使用反轉鏈表的方法)
  3. 用兩個指針分別指向兩條鏈表的頭節點,然後將第一條鏈表的當前節點指向第二條鏈表的當前節點,然後兩個節點都移動到下一位。

注意:
對鏈表的拆分應該注意後半段長度比前半段的小,這樣在第三步的時候才能正常完成鏈接。如果是前半段的長度比較小,那麼後半段的最後一個節點將得不到連接。因爲整個鏈表拆分爲2,所以前半段鏈表最多隻能比後半段鏈表大1個長度。

代碼

public class Solution {
    public void reorderList(ListNode head) {
        if (head == null || head.next == null) {
            return;
        }
        
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode p1 = head;
        ListNode p2 = reverse(slow.next);
        slow.next = null;
        
        while (p1 != null && p2 != null) {
            ListNode pNext = p1.next;
            p1.next = p2;
            p1 = pNext;
            
            pNext = p2.next;
            p2.next = p1;
            p2 = pNext;
        }
    }
    
    // 反轉鏈表的代碼
    public ListNode reverse(ListNode head) {
        ListNode cur = head;
        ListNode pre = null;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
}
發佈了34 篇原創文章 · 獲贊 3 · 訪問量 3850
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章