当前位置: 首页 > 知识库问答 >
问题:

返回单链表尾部(或尾部)的第k个元素

云远
2023-03-14

[采访问题]

编写一个函数,该函数将在一次传递中从单个链表整数的尾部(或尾部)返回第5个元素,然后提供一组针对该函数的测试用例。

这类似于问题:如何从单链表的末尾找到第n个元素?,但是我还有一个额外的要求,我们应该只遍历链接列表一次。

这是我的解决方案:

struct Lnode  
{
    int val;
    Lnode* next;
    Lnode(int val, Lnode* next=NULL) : val(val), next(next) {}
};


Lnode* kthFromTail(Lnode* start, int k)
{
   static int count =0;
   if(!start)
        return NULL;

   Lnode* end = kthFromTail(start->next, k);
   if(count==k) end = start;
   count++;
   return end;
}

我只遍历链表一次,并使用隐式递归堆栈。另一种方法是有两个指针:快指针和慢指针,快指针是比慢指针快的k个指针。哪一个看起来更好?我认为有两个指针的解决方案会很复杂,因为有很多例子,比如奇数长度列表,偶数长度列表,k

共有2个答案

欧阳鸿德
2023-03-14
'n' is user provided value. eg, 5 from last.

int gap=0 , len=0;
myNode *tempNode;

while (currNode is not NULL)
{
 currNode = currNode->next;
 gap = gap+1; 
 if(gap>=n)
   tempNode = currNode;
}
return tempNode;
谭兴学
2023-03-14

2指针解决方案不符合您的要求,因为它会遍历列表两次。

你的使用了更多的内存——确切地说是O(n)。您正在创建一个递归堆栈,其数量等于列表中的项数,这远远不够理想。

要从最后一项中查找第k项。。。

更好的(单次遍历)解决方案-循环缓冲区:

使用O(k)额外内存。

具有长度为k的数组。

对于每个元素,在数组的下一个位置插入(使用环绕)。

最后,只需将项目返回到数组中的下一个位置。

2点解决方案:

遍历列表两次,但仅使用O(1)个额外内存。

在开始处开始p1和p2

增加p1k倍。

而p1不在末尾

p2指向最后一个元素的第k个。

 类似资料:
  • 我第一次使用链表,必须创建一个可以在双链表末尾插入节点的函数。到目前为止我 Node类按顺序接受要存储的值、要指向的下一个指针的值和上一个指针的值。每当我试图在这里插入节点时,我都会得到一个错误,说有一个未处理的异常,并且在写入位置0x00000008时有访问冲突。 我不完全确定这里出了什么问题,但我认为这与根据错误消息取消引用空指针有关。我真的很感激有人帮忙解决这个问题。

  • 如果你想创建一个像这样的单链表: 这个列表有方法“追加”、“删除”、“printList”和“findElement”。有必要有尾巴吗?因为使用“最后”你可以地址最后一个节点。 那么,什么时候有必要拥有所有三个节点“头”、“尾”和“最后”?例如,当您想将排序的节点插入列表时?

  • 似乎人们总是说,如果一个单链接列表的头是空的,那么这个列表是空的,但是检查尾部也会起作用吗?假设我确实知道一个列表有一个尾部,我可以检查尾部是否为空以确定它是否为空吗?

  • 我在读一篇关于“新”C特性的文章时,遇到了decltype和它的用法。我理解decltype后面的原因,比如后面的返回类型 没有它,编译器将无法派生模板函数的返回类型。但是为什么语法是这样的呢? 为什么不使用 这会让人感觉更“自然”,因为返回类型是在正常情况下声明的,尽管这是两个参数的结果。这是因为它与其他东西冲突,还是因为如果语法是不值得的,它会给编译器带来额外的工作?

  • 尾部栏结构 Footer bar structure 尾部栏除了使用的data-role的属性与头部栏不同之外,基本的结构与头部栏是相同的 <div data-role="footer">   <h4>Footer content</h4> </div> 尾部工具栏默认下应用的主题样式为"a"(黑色),但是你可以很轻松的设置主题样式 默认的尾部栏 尾部栏的设置与头部栏基本相同。最大的不同是,

  • 我们不能轻易地删除单链表的最后一个节点。即使我们维护一个直接指向列表中最后一个节点的尾部引用,我们也必须能够在最后一个节点之前访问该节点,以便删除最后一个节点。但是我们不能通过从尾部跟随下一个链接到达尾部之前的节点。访问此节点的唯一方法是从列表的开头开始,在整个列表中进行搜索。但是这样一系列的链路跳转操作可能需要很长时间。