Leetcode 143. Reorder List(連結串列重新排序)
阿新 • • 發佈:2019-02-06
題目描述
思路分析
首先取得連結串列長度,然後反轉連結串列的後一半部分。然後開始連結串列重新排序(類似於洗牌一樣的)
程式碼實現
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
//獲取連結串列長度
private int getListOfLength(ListNode head) {
int n = 0;
while (head != null) {
n++;
head = head.next;
}
return n;
}
//反轉連結串列
private ListNode reverseList(ListNode head) {
ListNode pre = head;
ListNode p = pre.next;
ListNode next = null;
while (p != null) {
next = p.next;
p.next = pre;
pre = p;
p = next;
}
head.next = null ; //去掉頭結點的環
return pre;
}
//重新排序連結串列(連結串列洗牌)
public void reorderList(ListNode head) {
if (head == null || head.next == null) {
return;
}
int n = getListOfLength(head); //連結串列長度
int half = n/2; //連結串列長度的一半
if (n % 2 == 1) { //如果連結串列長度為奇數
half++;
}
ListNode leftEnd = head; //連結串列左半部分的結束位置,初始化為head
for (int i = 1; i < half; i++) {
leftEnd = leftEnd.next;
}
ListNode rightStart = leftEnd.next; //連結串列右半部分的開始位置
rightStart = reverseList(rightStart); //反轉連結串列的右半部分
leftEnd.next = null; //開始洗牌,將連結串列正中央的鏈斷開
ListNode left = head; //左半部分的開始位置
ListNode right = rightStart; //右半部分的開始位置
boolean flag = true; //實現交替洗牌
ListNode next = null; //用來儲存下一張洗的牌
//洗牌
while (right != null) {
if (flag) {
next = left.next;
left.next = right;
left = next;
} else {
next = right.next;
right.next= left;
right = next;
}
flag = !flag;
}
}
}