【问题标题】:Efficiently finding nth from last element in a linked list有效地从链表中的最后一个元素中找到第 n 个
【发布时间】:2016-11-21 16:01:33
【问题描述】:

在单/双链表中从最后一个元素中查找第 n 个元素的有效方法是什么?

【问题讨论】:

  • 这似乎毫无意义,没有比这种琐碎的方法更好的办法了。

标签: data-structures linked-list


【解决方案1】:

这是从链表中的最后一个元素中查找第 n 个元素的有效方法。

struct Node{
    int data;
    struct Node *next;
};

int getNthFromLast(struct Node *head, int n){
    struct Node *curr = head;
    struct Node *nthFromLast=NULL;
    int count=0;
    int value=-1;
    while(curr!=NULL){
        count++;
        curr=curr->next;
        if(count==n){
            nthFromLast=head;
        }else
            if(count>n){
                nthFromLast=nthFromLast->next;
            }
    }
    if(count>=n){
        value=nthFromLast->data;
    }
    return value;
}

这个例子是用 C++ 编写的,可以类似地用其他语言复制。该方法传递一个指向链表第一个节点的指针和最后一个元素的索引,它返回其数据。如果该位置不存在,则该方法返回 -1。

在双向链表和循环链表的情况下可以采用类似的方法。

编辑:如果是双向链表,只需反向移动 n 个项目。完全忘记了这一点。致谢:吉姆·米歇尔

【讨论】:

  • 有了一个双向链表,你所要做的就是从末尾倒数 n 个节点。另请注意,这与对列表进行完整扫描以查找计数,然后从头开始并向前推进(count-n) 次相比,效率基本上并没有提高或降低。
  • 同意双向链表点,有点忘了考虑这一点。感谢您强调这一点。会编辑。虽然,如果您先找到计数(loop 1),然后向前移动(count-n) 次,您不会徒劳地执行(count - n) 长度的第二个循环吗?如果说 n 的值在较小的一侧,那么您实际上将不得不遍历列表的一半以上而没有任何有意义的增益。所以我猜这就是第二个指针发挥作用的地方,它跟踪 (count-n) 项的位置。
  • 是的,但是如果您使用两次传递来执行此操作,那么您只会在循环中增加一个指针。在您的版本中,您最终会在一次传递中执行 count + (count-n) 指针增量。在两遍版本中,您在一遍中执行count 增量,在第二遍中执行(count-n) 增量。无论哪种方式,完成的工作量都是一样的。
  • 是的。虽然,对所有计算使用单个循环似乎更干净,因为它只涉及一次遍历。
猜你喜欢
  • 2013-12-10
  • 2014-01-11
  • 1970-01-01
  • 2023-03-09
  • 2016-01-22
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多