题目链接:
题目大意:
给定一个单向链表, 将链表中所有奇数位(序号为 2n + 1, n ∈ N) 的节点全部移到一起, 并放在偶数位的节点的前面 ;
( 题中还注明: 要求是 O(1) 的空间复杂度 和 O(n) 的时间复杂度, n 表示节点数 ; 且各节点间的相对位置保持不变(也即要求算法稳定) ; 同时链表中第一个节点视为奇数位, 第二个则是偶数位, etc )
例如: 给定链表节点顺序关系为: 1->2->3->4->5->NULL, 则输出的应是: 1->3->5->2->4->NULL ;
解题过程:
(1) 题目意思明显, 显然是遍历进行处理 ;
(2) 考虑到链表的 "顺序" 只是逻辑上的, 且其空间占用全由链表中的节点承担, 所以可以直接用 两个子链表 分别收纳原链表中的 奇数位的节点 和 偶数位的节点, 然后分别收集链接各自所属的节点, 最后首尾相连即可 ;
(*) 容易坑的点是, 因为原链表中的节点数可能为奇数(即原先由奇数位节点结束), 所以还要显式地将 偶数位节点组成的子链表的末端 链接至 nullptr 之类的东西 以确保处理后的链表中的最后一个节点(也即原先的最后一个偶数位节点) 已经成为链表的最后一个节点 ;
代码如下:
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
auto headOdd = head;
auto lastOdd = headOdd;
if (headOdd == nullptr) { return headOdd; }
auto headEven = head->next;
auto lastEven = headEven;
if (headEven == nullptr) { return headOdd; }
auto thisEven = lastEven;
while (thisEven != nullptr) {
auto nextOdd = thisEven->next;
if (nextOdd == nullptr) { break; }
lastOdd->next = nextOdd;
lastOdd = lastOdd->next;
auto nextEven = nextOdd->next;
if (nextEven == nullptr) { break; }
lastEven->next = nextEven;
lastEven = lastEven->next;
thisEven = nextEven;
}
lastOdd->next = headEven;
lastEven->next = nullptr;
return headOdd;
}
};
Runtime: 16 ms