排序奇升偶降链表
题目描述 : 给定一个奇数位升序,偶数位降序的链表,将其重新排序。
输入: 1->8->3->6->5->4->7->2->NULL 输出: 1->2->3->4->5->6->7->8->NULL
要求: 时间复杂度为O(N),空间复杂度O(1)。
思路:
1. 按奇偶位置拆分链表,得1->3->5->7->NULL和8->6->4->2->NULL
2. 反转偶链表,得1->3->5->7->NULL和2->4->6->8->NULL
3. 合并两个有序链表,得1->2->3->4->5->6->7->8->NULL
代码:
class Solution {
/**
* 1. 拆分奇偶链表
* 2. 翻转偶数链表
* 3. 合并有序链表
*/
public static ListNode sortList(ListNode list) {
// 1. 拆分奇偶链表
ListNode[] arr = separate(list);
// 2. 翻转偶数链表
ListNode oddList = arr[0];
ListNode evenList = reverse(arr[1]);
// 3. 合并有序链表
return mergeSortedLists(oddList, evenList);
}
private static ListNode mergeSortedLists(ListNode oddList, ListNode evenList) {
ListNode dummyNode=new ListNode();
ListNode cur=dummyNode;
while(oddList!=null || evenList!=null){
if(oddList!=null){
cur.next=oddList;
oddList=oddList.next;
cur=cur.next;
cur.next=null;
}
if(evenList!=null){
cur.next=evenList;
evenList=evenList.next;
cur=cur.next;
cur.next=null;
}
}
return dummyNode.next;
}
private static ListNode reverse(ListNode listNode) {
if(listNode==null || listNode.next==null) return listNode;
ListNode newHead=reverse(listNode.next);
listNode.next.next=listNode;
listNode.next=null;
return newHead;
}
private static ListNode[] separate(ListNode list) {
if (list == null || list.next == null) return new ListNode[]{list, null};
ListNode dummyNode = new ListNode();
ListNode cur = dummyNode;
ListNode p = list;
while(p!=null && p.next!=null){
cur.next=p.next;
cur=cur.next;
p.next=p.next.next;
p=p.next;
cur.next=null;
}
return new ListNode[]{list,dummyNode.next};
}
public static void main(String[] args) {
ListNode listNode = sortList(new ListNode(1, new ListNode(8, new ListNode(3, new ListNode(6, new ListNode(5,
new ListNode(4, new ListNode(7, new ListNode(2)))))))));
System.out.println(listNode);
}
}
感谢大佬 @chenchen4396 提供的优化思路:
- 直接记住第一个和第二个节点的位置,遇到奇数插在头节点后面,偶数插在尾节点前面
class Solution {
/**
* 1. 记住前两个节点,奇数尾插,偶数头插
* 2. 合并有序链表
*/
public static ListNode sortList(ListNode list) {
// 1. 链表小于两个节点,直接返回
if (list == null || list.next == null) return null;
// 2. 记住前两个节点,奇数尾插,偶数头插
ListNode oddList = new ListNode(), cur = oddList;
ListNode evenList = null;
int i = 1;
while (list != null) {
if ((i++) % 2 == 1) {
cur.next = list;
cur = cur.next;
list = list.next;
cur.next = null;
} else {
ListNode next = list.next;
list.next = evenList;
evenList = list;
list = next;
}
}
// 3. 合并有序链表
return mergeSortedLists(oddList.next, evenList);
}
private static ListNode mergeSortedLists(ListNode oddList, ListNode evenList) {
ListNode dummyNode = new ListNode();
ListNode cur = dummyNode;
while (oddList != null || evenList != null) {
if (oddList != null) {
cur.next = oddList;
oddList = oddList.next;
cur = cur.next;
cur.next = null;
}
if (evenList != null) {
cur.next = evenList;
evenList = evenList.next;
cur = cur.next;
cur.next = null;
}
}
return dummyNode.next;
}
public static void main(String[] args) {
ListNode listNode = sortList(new ListNode(1, new ListNode(8, new ListNode(3, new ListNode(6, new ListNode(5,
new ListNode(4, new ListNode(7, new ListNode(2)))))))));
System.out.println(listNode);
}
}

