BM14 链表的奇偶重排
知识点链表排序
描述
给定一个单链表,请设定一个函数,将链表的奇数位节点和偶数位节点分别放在一起,重排后输出。注意是节点的编号而非节点的数值。
数据范围:节点数量满足 ,节点中的值都满足
要求:空间复杂度 ,时间复杂度
示例1
输入:
{1,2,3,4,5,6}
复制返回值:
{1,3,5,2,4,6}
复制说明:
1->2->3->4->5->6->NULL重排后为1->3->5->2->4->6->NULL
示例2
输入:
{1,4,6,3,7}
复制返回值:
{1,6,7,4,3}
复制说明:
1->4->6->3->7->NULL重排后为
1->6->7->4->3->NULL
奇数位节点有1,6,7,偶数位节点有4,3。重排后为1,6,7,4,3
题解:
思路:
通过一次遍历链表,使用2个指针分别指向第一个、第二个节点,分别代表odd和even链表,让这两个节点每次往前跳动2个节点,使用odd和even链表分别将这些节点串联起来,当这两个节点的next节点中有一个为空的时候,将两个链表串联起来,返回odd的头节点即可。实现如下:
struct ListNode
{
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(nullptr)
{
}
ListNode() = default;
};
ListNode *oddEvenList(ListNode *head)
{
if (head == nullptr || head->next == nullptr)
{
return head;
}
auto odd = head;
auto even = head->next;
auto odd_tail = odd;
auto even_tail = even;
while (true)
{
if (odd_tail->next == nullptr || even_tail->next == nullptr)
{
odd_tail->next = even;
break;
}
auto odd_next = even_tail->next;
auto even_next = odd_next->next;
odd_tail->next = odd_next;
even_tail->next = even_next;
odd_tail = odd_next;
even_tail = even_next;
}
return odd;
}
ListNode *create_list(const std::vector<int> &v)
{
ListNode head;
ListNode *phead = &head;
for (auto &data : v)
{
auto node = new ListNode;
node->val = data;
node->next = nullptr;
phead->next = node;
phead = phead->next;
}
return head.next;
}
int main()
{
// auto list = create_list(std::vector<int>{105, 25, 89, 67, 49, 38, 52});
auto list = create_list(std::vector<int>{1, 3, 2, 4, 5, 6});
auto head = oddEvenList(list);
while (head != nullptr)
{
std::cout << head->val << " ";
head = head->next;
}
std::cout << std::endl;
return 0;
}