题目描述
给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数
什么是原地算法
In computer science, an in-place algorithm is an algorithm which transforms input using no auxiliary data structure.
However a small amount of extra storage space is allowed for auxiliary variables.
The input is usually overwritten by the output as the algorithm executes.
In-place algorithm updates input sequence only through replacement or swapping of elements.
An algorithm which is not in-place is sometimes called not-in-place or out-of-place.
——摘自原地算法的维基百科
一句话总结就是: 原地算法不依赖额外的资源或者依赖少数的额外资源,仅依靠输出来覆盖输入的一种算法操作。
对于数组来说,不能够创建新的数组,
对于链表来说,没有什么实质影响。
方法一,奇偶分离,将奇数节点连在一起,偶数节点连在一起,最后将奇数链表的尾节点连接到偶数链表的头节点即可
class Solution {
public ListNode oddEvenList(ListNode head) {
if (head == null) {
return head;
}
ListNode evenHead = head.next;
ListNode odd = head, even = evenHead;
while (even != null && even.next != null) {
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}
odd.next = evenHead;
return head;
}
}
方法二,原链表直接交换节点。
class Solution {
public ListNode oddEvenList(ListNode head) {
if(head==null || head.next==null){
return head;
}
//应该有三个临时节点,一个节点指向前一个奇数节点,一个节点指向后一个奇数节点,还有一个节点执行后一个奇数节点的前一个节点。
//前一个奇数节点
ListNode pre = head;
//后一个奇数节点的前一个节点
ListNode cur = head.next;
//后一个奇数节点
ListNode prenext = head.next.next;
while(cur!=null && prenext!=null){
cur.next = prenext.next;
prenext.next = pre.next;
pre.next = prenext;
//开始下一轮初始化
pre = prenext;
cur = cur.next;
if(cur!=null){
prenext = cur.next;
}
}
return head;
}
}