牛客網高頻演算法題系列-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$
相信堅持的力量!