148. Sort List
Sort a linked list in O(n log n) time using constant space complexity.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
//第一种方法,mergeSort
//①找中点
//②把两边排好序
//③merge两个有序数组
// class Solution {
// //寻找中点,通过快慢指针实现
// public ListNode findMiddle(ListNode head){
// ListNode fast = head.next,slow = head;
// while(fast!=null && fast.next!=null){
// slow = slow.next;
// fast = fast.next.next;
// }
// return slow;
// }
// public ListNode merge(ListNode left,ListNode right){
// ListNode dummpy = new ListNode(0);
// ListNode lastNode = dummpy;
// while(left != null && right != null){
// if(left.val < right.val){
// lastNode.next = left;
// left = left.next;
// }else{
// lastNode.next = right;
// right = right.next;
// }
// lastNode = lastNode.next;
// }
// if(left != null)
// lastNode.next = left;
// if(right != null)
// lastNode.next = right;
// return dummpy.next;
// }
// public ListNode sortList(ListNode head) {
// if(head == null || head.next == null) return head;//如果不加head.next==null会陷入死循环
// ListNode middle = findMiddle(head);
// ListNode left = sortList(middle.next);
// middle.next = null;
// ListNode right = sortList(head);
// return merge(left,right);
// }
// }
//第二种方法,quickSort
//①找中点
//②根据中点partition List
//③对两个链表分别排序
//④连接链表
class Solution {
//寻找中点,通过快慢指针实现
public ListNode findMiddle(ListNode head){
ListNode fast = head.next,slow = head;
while(fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public ListNode getTail(ListNode head){
if(head == null) return head;
while(head.next!= null)
head = head.next;
return head;
}
public ListNode concat(ListNode left,ListNode middle,ListNode right){
ListNode dummpy = new ListNode(0), tail = dummpy;
tail.next = left;tail = getTail(tail);
tail.next = middle;tail = getTail(tail);
tail.next = right;
return dummpy.next;
}
public ListNode sortList(ListNode head) {
if(head == null || head.next == null) return head;//如果不加head.next==null会陷入死循环
ListNode middle = findMiddle(head);
//partition链表
ListNode leftDummpy = new ListNode(0),leftTail = leftDummpy;
ListNode rightDummpy = new ListNode(0),rightTail = rightDummpy;
ListNode middleDummy = new ListNode(0), middleTail = middleDummy;
while(head != null){
if(head.val < middle.val){
leftTail.next = head;
leftTail = head;
}else if(head.val > middle.val){
rightTail.next = head;
rightTail = head;
}else{
middleTail.next = head;
middleTail = head;
}
head = head.next;
}
leftTail.next = null;
middleTail.next = null;
rightTail.next = null;
ListNode left = sortList(leftDummpy.next);
ListNode right = sortList(rightDummpy.next);
return concat(left,middleDummy.next,right);
}
}
143. Reorder List
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You must do this in-place without altering the nodes' values.
For example,
Given {1,2,3,4}
, reorder it to {1,4,2,3}
.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
//寻找中点
//根据中点把链表分成两半,并且逆转右边
//merge两个左右链表
class Solution {
public void reorderList(ListNode head) {
if(head == null || head.next == null) return ;
ListNode middle = findMiddle(head);
ListNode tail = reverse(middle.next);
middle.next = null;
merge(head,tail);
}
public ListNode findMiddle(ListNode head){
ListNode slow = head,fast = head.next;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public ListNode reverse(ListNode head){
ListNode pre = null;
while(head != null){
ListNode temp = head.next;
head.next = pre;
pre = head;
head = temp;
}
return pre;
}
public void merge(ListNode head,ListNode tail){
ListNode dummpy = new ListNode(0);
int index = 0;
while(head != null && tail != null){
if(index % 2 == 0){
dummpy.next = head;
head = head.next;
}else{
dummpy.next = tail;
tail = tail.next;
}
index++;
dummpy = dummpy.next;
}
if(head != null)
dummpy.next = head;
else
dummpy.next = tail;
}
}