【问题标题】:Read linked list backwards without changing it向后读取链表而不更改它
【发布时间】:2016-06-06 14:46:09
【问题描述】:

给定一个单向链表,向后读取该链表。这听起来像一个简单的问题但是(!)你不能改变链表的指针,你只能使用 3 个变量(指针或其他变量),每个单元格都有一个以 false 开头的 bool 标志,你可以使用它如你所愿。

在 O(n^2) 中很容易做到,但我认为有更好的解决方案(也许 O(n)?)。

【问题讨论】:

  • 但是为什么呢?这是学术练习吗?
  • 使用堆栈:将所有列表元素压入其中,然后您可以以相反的顺序将它们拉出。那将是O(n)
  • 你可以递归地解决它......你从头部开始,调用下一个(递归地)直到你在尾部或nullptr......然后递归关闭,你可以打印出价值...它比 O(n) 所以在线性时间内
  • 是的,但它也很有用,因为指针很重,计算机很难改变它们的值
  • @OferMagen 到目前为止您尝试过什么?这听起来像是家庭作业。

标签: algorithm linked-list


【解决方案1】:

这种递归方法仅适用于对列表进行 1 次迭代。所以它是O(n)。

它是如何工作的:

它在列表中递归,直到它在最后,并在堆栈帧上添加一个方法调用。最后它打印出最后一个节点并返回到第二个最后的方法调用(它通过堆栈帧返回)

void RecursiveBackwardPrint(node* node)
{
    if(node->next != nullptr)
    {
        RecursiveBackwardPrint(node->next);
    }
    std::cout<<node->value<<std::endl;
}

【讨论】:

  • @Ofer Magen:这是你所期望的吗?还是我理解错了问题?
【解决方案2】:

您可以在 O(n) 中完成,每次组合 32 个布尔值,以便将它们转换为指向前一个 32 个元素块的指针。

算法:

  • 读取列表的最后一个元素以使列表大小为 % 32。(O(n*32) = O(n))
  • 在元素 32 到 63 中使用布尔值来存储指向开头的指针,在元素 64 到 95 中使用布尔值来存储指向元素 32 的指针,依此类推 (O(n))
  • 转到最后 32 个块 (O(n)),读取它们 (O(32)),跳回到最后 64 个块 (O(1)),按倒序读取接下来的 32 个块 (O(32) ),跳回最后 96 个区块,以此类推。

它是 O(n),但至少需要 32*n 次操作,仅对于非常长的列表才值得。

【讨论】:

    猜你喜欢
    • 2010-11-10
    • 2011-07-04
    • 2022-12-10
    • 2018-02-07
    • 1970-01-01
    • 2016-11-22
    • 2011-02-26
    • 1970-01-01
    • 2021-09-04
    相关资源
    最近更新 更多