力扣原题:
先贴代码:
public class Solution328 {
public ListNode oddEvenList(ListNode head) {
//当链表为空时,直接返回
if (head == null){
return head;
}
//创建节点oddnum和节点evennum,始终指向奇数和偶数的最后一个节点
ListNode oddnum = head;
ListNode evennum = head.next;
//当evennum为最后一个节点时循环结束
while (evennum != null && evennum.next != null){
//创建一个cur指针,指向evennum的后继节点
ListNode cur = evennum.next;
//将evennum后面的那个奇数节点移到前面
evennum.next = cur.next;
cur.next = oddnum.next;
oddnum.next = cur;
//evennum和oddnum后移一步
oddnum = oddnum.next;
evennum = evennum.next;
}
return head;
}
}
思路解析:
本题中要求我们将奇数节点和奇数节点排在一起,偶数节点和偶数节点排在一起,奇数和偶数指的是节点的编号;并且还要我们使用原地算法完成。所以我们就需要直接在链表内进行操作。
因为需要将一条链表分为奇数部分和偶数部分,所以我们先创建两个指针oddnum(奇数)和evennum(偶数),分别指向奇数部分的最后一个节点和偶数部分的最后一个节点,这样就可以将evennum的后继节点移至oddnum的后面,因为evennum指向的是偶数节点,所以它的后继节点一定是奇数的节点。
将evennum的后继节点移至oddnum后面后,再把它们两个都往后移动一步,这样就会始终指向奇数或者偶数部分的最后一个节点。
因为题目要求奇数部分在前,偶数部分在后,所以我们就可以用evennum来判断循环结束:当evennum为空或者evennum的后继节点为空时,表示链表已经全部走完,此时就可以结束循环了。最后返回head头节点。