很有可能。我想出了一个解决方案,可能不是最优的,但表明它可以完成。首先将其分为两个问题:反转下一个指针和反转随机指针。
反转下一个指针:
node* last = NULL;
node* current = head;
node* next = head->next;
while (current != NULL)
{
current->next = last;
last = current;
current = next;
if (current != NULL)
next = current->next;
}
head = last
将随机列表反转有点棘手,因为我们没有所有随机指针链头的列表,但是我们可以找到它们的末尾(节点将具有NULL随机指针)。我们需要几个辅助函数来完成此操作。第一个是用于反转随机列表的函数。我们大部分代码从上面复制。请注意,我们将链的末尾设置为特殊值。这样可以防止我们重新反转列表。有关说明,请参见注释中的讨论。
node* chainTail = malloc(1); //mallocing here to get a unique pointer
void reverseRandom(node* rhead)
{
node* last = chainTail;
node* current = rhead;
node* next = rhead->random;
while (current != NULL)
{
current->random = last;
last = current;
current = next;
if (current != NULL)
next = current->random;
}
}
我们还需要一个帮助函数来查找一个节点的父节点(如果没有则返回NULL)。我们将进行简单的线性搜索:
node* findParent(node* target)
{
node* candidate = head;
while ((candidate != NULL) && (candidate->random != target))
candidate = candidate->next;
return candidate;
}
现在我们只需遍历列表,找到任何随机值为NULL的节点(我们的链尾),找到它们的链头并反转这些链:
node* current = head;
while (current != NULL)
{
if (NULL == current->random)
{
node* curr = current;
node* parent = findParent(curr);
while (parent != NULL)
{
curr = parent;
parent = findParent(curr);
}
reverseRandom(curr);
}
current = current->next;
}
node* current;
for (current = head; current != NULL; current = current->next)
{
if (current->random == chainTail)
{
current->random = NULL;
}
}
free(chainTail);
免责声明:我并没有运行这段代码。它可能存在漏洞。在接近结尾时,我开始感到困倦,所以可能存在逻辑错误,但我认为它能够正常工作。
另外,如果您想要将此代码投入生产,请不要这么做。该代码的运行时间大约为O(n^3),很可能不是最快的解决方案。尽管如此,它确实使用了恒定的空间(虽然甚至可以通过内联和积极的变量共享来进一步减少空间占用)。