24. Swap Nodes in Pairs + 25. Reverse Nodes in k-Group

▶ 问题:单链表中的元素进行交换或轮换。

▶ 24. 每两个元素进行翻转。如 [1 → 2 → 3 → 4 → 5] 变换为 [2 → 1 → 4 → 3 → 5]

● 初版代码,4 ms

 class Solution
{
public:
ListNode* swapPairs(ListNode* head)
{
int length;
ListNode newHead(-), *x, *y;
newHead.next = head; // 添加头结点,方便操作原链表的首元
for (x = head, length = ; x != nullptr; x = x->next, length++);// 计算链表元素个数
if (length <= ) // 无需交换的情形
return head;
for (x = &newHead, y = x->next; y != nullptr && y->next != nullptr; x = x->next->next, y = y->next)
{ // y 指向需要交换的两个节点的靠前一个,x 指向 y 的再前一个节点
x->next = x->next->next;
y->next = x->next->next;
x->next->next = y;
}
return newHead.next;
}
};

● 改良版代码,3 ms 。减少了结点计数,改变了操作顺序,后面 k 元轮换的算法与此类似。

 class Solution
{
public:
ListNode* swapPairs(ListNode* head)
{
if (head == nullptr || head->next == nullptr)// 0 或 1 个元素
return head;
ListNode newHead(-);
newHead.next = head;
for (ListNode *x = &newHead, *y = x->next->next;;)// y指向需要交换的两个元素的后者
{
x->next->next = x->next->next->next;
y->next = x->next;
x->next = y;
x = y->next; // 一定存在,不用检查 nullptr
if (x->next == nullptr || (y = x->next->next) == nullptr)
break;
}
return newHead.next;
}
};

▶ 25. 每 k 个元素进行翻转。如 k = 4 时,[1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9] 变换为 [4 → 3 → 2 → 1 → 8→ 7 → 6 → 5 → 9]

● 自己的代码,26 ms

 class Solution
{
public:
ListNode* reverseKGroup(ListNode* head, int k)
{
int length, front;
ListNode newHead(-), *x, *y, *z, *w;
for (x = head, length = ; x != nullptr; x = x->next, length++);// 求链表长,是否还剩 k 元可以进行轮换由 length 决定
if (length < || k < || length < k) // 不需要调整的情形
return head;
for (front = , newHead.next = head, x = &newHead; (length - front) / k;)// front 代表当前处理的元素的最大序号(w 指向的元素的编号)
{
y = x, z = y->next, w = z->next;
for (front++; front % k; front++)// 每次循环先跳转 y、z、w 建立一个链接
{
y = z, z = w, w = w->next;
z->next = y;
}
x->next->next = w; // 之后建立与 x 有关的链接
y = x->next;
x->next = z;
x = y;
}
return newHead.next;
}
};

● 大佬的代码,25 ms

 class Solution
{
public:
ListNode* reverseKGroup(ListNode* head, int k)
{
ListNode *node = head, *rev;
for (int i = ; i < k; node = node->next, i++)
{
if (node == NULL)
return head;
}
rev = reverse(head, node);
head->next = reverseKGroup(node, k);
return rev;
}
ListNode * reverse(ListNode *start, ListNode *end)
{
ListNode *prev = end, *next;
while (start != end)
{
next = start->next;
start->next = prev;
prev = start;
start = next;
}
return prev;
}
};
上一篇:【题解】洛谷P1273 有线电视网(树上分组背包)


下一篇:【转】STM32: 一种计算CPU使用率的方法及其实现原理