来看一下几篇面经的原文叙述
- 链表,奇数位置按序增长,偶数位置按序递减,如何能实现链表从小到大?(2020.10 字节跳动-后端)[2]
- 奇偶生序倒序链表的重新排序组合,例如:18365472(2020.08 字节跳动-后端)[3]
- 1->4->3->2->5 给定一个链表奇数部分递增,偶数部分递减,要求在O(n)时间复杂度内将链表变成递增,5分钟左右(2020.07 字节跳动-测试开发)[4]
- 奇数位升序偶数位降序的链表要求时间O(n)空间O(1)的排序?(2020.07 字节跳动-后端)[5]
思路很清晰,实现起来其实还是有些难度的,因为这里的每一步其实都可以单独抽出来作为一道题。第2步和第3步分别对应的力扣206. 反转链表和21. 合并两个有序链表,而第1步的解法与328. 奇偶链表差不多。如果搞懂这3道leetcode,那么本篇文章的这道题肯定不在话下了。
public ListNode Solution(ListNode head){
List<ListNode> list = splitOddEvenList(head);
ListNode oddHead = list.get(0);
ListNode evenHead = list.get(1);
evenHead = reverEvenList(evenHead);
return mergeOddEvenList(oddHead, evenHead);
}
//奇偶链表拆分
public List<ListNode> splitOddEvenList(ListNode oddhead){
ListNode evenHead = oddhead.next;
ListNode curEven = evenHead;
ListNode curOdd = oddhead;
while(curOdd!=null && curOdd.next!=null){
curOdd.next = curOdd.next.next;
curOdd = curOdd.next;
if(curOdd==null) break;
curEven.next = curOdd.next;
curEven = curEven.next;
}
return new LinkedList<ListNode>(Arrays.asList(oddhead,evenHead));
}
//反转链表
public ListNode reverEvenList(ListNode node){
if(node==null || node.next==null) return node;
ListNode newHead = reverEvenList(node.next);
node.next.next = node;
node.next = null;
return newHead;
}
// 合并链表
public ListNode mergeOddEvenList(ListNode oddHead,ListNode evenHead){
if(oddHead==null) return evenHead;
if(evenHead==null) return oddHead;
if(oddHead.val<=evenHead.val){
oddHead.next = mergeOddEvenList(oddHead.next,evenHead);
return oddHead;
}else{
evenHead.next = mergeOddEvenList(oddHead,evenHead.next);
return evenHead;
}
}