牛客網高頻演算法題系列-BM14-連結串列的奇偶重排

雄獅虎豹 發表於 2022-06-13
演算法

牛客網高頻演算法題系列-BM14-連結串列的奇偶重排

題目描述

給定一個單連結串列,請設定一個函式,將連結串列的奇數位節點和偶數位節點分別放在一起,重排後輸出。
注意是節點的編號而非節點的數值。

原題目見:BM14 連結串列的奇偶重排

解法一:連結串列遍歷(使用額外空間)

首先,判斷如果連結串列為空或者只有1或2個結點,不用重排,直接返回原連結串列。

否則,使用2個list額外記錄奇數和偶數位的結點,處理過程如下:

  • 遍歷連結串列,分別將奇數和偶數位的結點值放到不同的list中;
  • 按照奇數位在前、偶數位在後的順序,將2個list中的值重組成新的連結串列即為重排後的連結串列,返回之。

解法二:雙指標法

同樣的,首先要判斷如果連結串列為空或者只有1或2個結點,不用重排,直接返回原連結串列。

否則,使用odd和even結點分別指向連結串列的第一個(奇數)和第二個(偶數)結點,然後遍歷連結串列,將奇數位的結點和偶數位的結點分別連線起來,最後,將偶數位的放到奇數位的連結串列後面,即為重排後的連結串列。

程式碼

import java.util.ArrayList;
import java.util.List;

public class Bm014 {
    /**
     * 使用額外的空間
     *
     * @param head ListNode類
     * @return ListNode類
     */
    public static ListNode oddEvenList(ListNode head) {
        // 如果連結串列為空或者只有1或2個結點,不用重排
        if (head == null || head.next == null || head.next.next == null) {
            return head;
        }
        // 奇數結點
        List<Integer> odds = new ArrayList<>();
        // 偶數結點
        List<Integer> evens = new ArrayList<>();

        int i = 1;
        while (head != null) {
            if (i % 2 == 1) {
                odds.add(head.val);
            } else {
                evens.add(head.val);
            }
            head = head.next;
            i++;
        }

        ListNode newHead = new ListNode(-1), cur = newHead;
        for (Integer val : odds) {
            cur.next = new ListNode(val);
            cur = cur.next;
        }
        for (Integer val : evens) {
            cur.next = new ListNode(val);
            cur = cur.next;
        }

        return newHead.next;
    }

    /**
     * 雙指標法
     *
     * @param head
     * @return
     */
    public static ListNode oddEvenList2(ListNode head) {
        // 如果連結串列為空或者只有1或2個結點,不用重排
        if (head == null || head.next == null || head.next.next == null) {
            return head;
        }

        // 奇數結點
        ListNode odd = head;
        // 偶數結點,偶數連結串列頭
        ListNode evenHead = head.next, even = evenHead;
        while (even != null && even.next != null) {
            // odd連線奇數位結點
            odd.next = even.next;
            odd = odd.next;
            // even連線偶數位結點
            even.next = odd.next;
            even = even.next;
        }
        // 最後將odd連結串列的最後一個結點指向even連結串列的表頭
        odd.next = evenHead;
        return head;
    }

    public static void main(String[] args) {
        ListNode head = ListNode.testCase5();
        System.out.println("原連結串列為");
        ListNode.print(head);

        System.out.println("重排後的連結串列為");
        ListNode.print(oddEvenList(head));
        ListNode.print(oddEvenList2(head));
    }
}
$1.01^{365} ≈ 37.7834343329$
$0.99^{365} ≈ 0.02551796445$
相信堅持的力量!

相關文章