题目:
给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
示例 1:
输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL
说明:
- 应当保持奇数节点和偶数节点的相对顺序。
- 链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。
思路:
将链表分成2部分:奇数部分和偶数部分,然后连接起来并返回。
设置2个指针odd和even,分别指向奇数和偶数的节点,每次移动,odd和even指针移动2个单位。最后将奇数链表和偶数链表连接起来,返回。
参考代码:
public static ListNode oddEvenList(ListNode head) {
if(head == null || head.next == null)return head;
//odd指向奇数节点
ListNode odd = head;
//even指向偶数节点
ListNode even = head.next;
//evenHead指向偶数链表头结点
ListNode evenHead = even;
//注意这里的循环条件
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;
}
特别需要注意while的循环条件和中间的&&,不是||。
-
如图,有3(奇数)个结点时,1次指针移动后,even指向null,即even = null时,此时应该终止循环,得到奇数链表的最后一个结点odd。
-
当链表中结点个数有(偶数)4个时,又是另外一种情况:
此时偶数结点even的下一个结点为null,则even.next !=null 为循环终止条件。此时得到奇数链表的最后一个结点odd。
-
将以上2者写到while循环中时,要特别注意2点:
even != null && even.next != null 不能写成even.next != null && even != null,否则可能抛异常。
中间用 && 来进行连接,如果用||会出错。若为||,结点数目为4个时的情况下,1次循环后满足even!= null,此时执行循环语句出错。
小结
该题思路基本都能想到,但是自己在循环结束条件上花了好多时间,以后得特别注意。