原文链接:字节跳动高频面试题之排序奇升偶降链表_Erazer_Control-CSDN博客
题目描述
给定一个奇数位升序,偶数位降序的链表,将其重新排序。
输入: 1->8->3->6->5->4->7->2->NULL
输出: 1->2->3->4->5->6->7->8->NULL
复制代码
题目分析
按奇偶位置拆分链表,得1->3->5->7->NULL和8->6->4->2->NULL
反转偶链表,得1->3->5->7->NULL和2->4->6->8->NULL
合并两个有序链表,得1->2->3->4->5->6->7->8->NULL
思路很清晰,实现起来有些难度。第2步和第3步分别对应的力扣206. 反转链表和力扣21. 合并两个有序链表,而第1步的解法与力扣328. 奇偶链表差不多。
如果搞懂这3道leetcode,那么本篇文章的这道题肯定不在话下了。
class Solution{
private ListNode[] partition(ListNode){
ListNode evenHead = head.next;
ListNode odd = head;
ListNode even = evenHead;
while(even != null && even.next != null){
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}
odd.next = null;
return new ListNode[]{head, evenHead};
}
private ListNode reverse(ListNode head){
ListNode pre = null;
while(head != null){
ListNode nx = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
private merge(ListNode p, ListNode q){
ListNode head = new ListNode();
ListNode r = head;
while(p != null && q != null){
if(p.val <= q.val){
r.next = p;
p = p.next;
}else{
r.next = q;
q = q.next;
}
r = r.next;
}
if(p != null)
r.next = p;
if(q != null)
r.next = q;
return head.next;
}
public sortOddEvenList(ListNode head){
if(head == null || head.next == null)
return head;
ListNode[] tmp = partition(head);
ListNode oddList = tmp[0];
ListNode evenList = tmp[1];
return merge(oddList, evenList);
}
}