用于在链表中查找结点的生产代码

2024-06-19

我在一次采访中被问到这个问题。

我被要求编写代码,用于在 O(1) 空间和线性时间的生产环境中在链表(其形式为 Y 形式,双臂不一定相等)中查找结点。
我想出了这个解决方案(我以前在某处见过):



1. Measure lengths of both lists, let them be l1 and l2 
2. Move the pointer of larger list by |(l1-l2)|.
3. Now move together both the pointers, if they point to same location,
that is the junction.
  
Interviewer: How will your code handle ?
Case 1. The Y-format linked list has loop in the end after the junction.
Case 2. Either of the input lists is cyclic and they don't merge.
Case 3. The Y-format list has loop in the end before the junction.

针对案例1,我的回答是:

I will find the loop in the list using two pointers (one fast and slow), measure the length to the node at which both the pointers meet and then proceed as previous case.
Whereas, for cases 2 and 3, I was able to figure out no better solution than gracefully exiting when a loop is detected (using the 2-pointer technique).


我相信这个问题有更好的答案。请放下你的:)。

Thanks,


面试官(看似)的解释使问题变得困难,即以下形状也被认为是有效的:

A\  _____     A\              ___
  \/     \      \            /   \
   \     /       \           \   /
    +---'         +-------------'
   / P           / P
  /             /
B/            B/

即存在一个交汇点,但列表会循环回到交汇点之前或之后的位置。计算列表长度的过程并没有直接帮助,因为循环列表的长度没有定义。

首先请注意,循环列表末尾的循环长度可以通过以下 O(1) 内存 / O(n) 时间过程来计算:

int loop_length(List *n) {
  Node *hare = n, *tortoise = n;
  int phase = 0, cnt = 0;
  while (true) {
    hare=hare->next; hare=hare->next; tortoise=tortoise->next;
    if (hare==tortoise) phase++; 
    if (phase==1) cnt++;
    if (phase==2) return cnt;
  }
}

例如,考虑循环列表

(1)-->(2)-->(3)-->(4)
             |     |
            (6)<--(5)

该算法的工作原理如下(T=乌龟,H=野兔):

       /--------\
 1--2--3--4--5--6    phase  cnt
 HT                  0      0
    T  H             0      0
       T     H       0      0
          HT         1      1
             T  H    1      2
           H    T    1      3
       T        H    1      4
          HT         2      4 : TERMINATED, cnt=4

现在,如果在构成循环交汇点的节点(在示例中节点(3)中)之前有 X 个节点,即 X=2,并且循环由 C 个节点组成(在示例中 C=4),则当乌龟在 X 步后第一次进入交汇点,兔子在位置 (2X - X) % C 处进入循环,即 (X % C)(在示例中,乌龟在 2 步后进入 (3),第 3 只兔子是然后在位置 L = (2 % 4 = 2),即在节点 (5) 中(索引从零开始)。现在兔子需要 (C-L-1) 步才能到达乌龟(在示例)因为野兔有 L 个步骤的“优势”;这意味着直到野兔第一次遇到乌龟之前算法的步骤数为

  X + (C - X % C - 1)     ; in the example 2 + (4 - 2 - 1) = 3

C已知(由算法计算),可以计算出总步数(用S表示),即我们有

  S + 1 - C = X - X % C

现在假设野兔作为 Q 步的额外优势,即野兔在算法开始之前向前移动前 Q 个下一个指针;然后当乌龟进入交汇点时,兔子位于 ((X + Q) % C) 位置,我们得到

  S + 1 - C = X - (X + Q) % C

现在给出了计算从“A”和“B”到公共交汇点 P 的路径长度差的过程(表示长度 a 和 b 以及它们的差 a-b)(假设 a > b 且不损失概论)。

首先从起点A运行算法,计算循环长度C并存储步数S_A。然后运行它,使乌龟从 A 开始,野兔在B并计算步数S_X。这意味着野兔现在具有 (a-b) 节点的优势,即

  S_X + 1 - C = a - (a + (a - b)) % C = a - (2a - b) % C

Thus

  S - S_X == (a - b)   modulo   C

IE。差值给出了模 C 的长度差;要计算 C 的长度差商,通常从起点 B 运行算法,得到步数 S_B,即全部在一起

  S_A + 1 - C = a - a % C
  S_B + 1 - C = b - b % C
  S_X - S_A == (a - b) % C

减去前两个方程得到

  S_A - S_B = (a - b) + [-1 * (a % C) + b % C]

方括号中的项位于 ]-C,+C[ 中​​,因此

  (S_A - S_B) - C < (a - b) < (S_A - S_B) + C

在此区间内,至多有两个差值等于 (S - S_X) 模 C;用它们来尝试找出连接点——问题就解决了。

Example:

 A(1)--(2)
        |
 B(3)--(4)--(5)--(6)
        \_________/

在S_A的计算中,兔子和乌龟在(5)处经过3步后相遇,返回周期长度3。在S_B的计算中,兔子和乌龟在(6)处经过3步后相遇,返回周期长度3。对于S_X,兔子从B进入,乌龟从A进入;两步后他们在 (4) 处相遇。这给出了

  0 - 3 < (a - b) < 0 + 3
  (3 - 2) == (a - b)  modulo  3

即(a - b)之间的长度差是1模3;这给出了可能的长度差异 { -2, +1 }; -2 被假设 a > b 忽略,所以我们得到 a = b + 1。 然后通过从 A 向前遍历第一个 +1 节点到 (2),然后从双臂以相同的速度前进,找到交汇点,直到找到了交汇点。

与存在非共享循环和/或没有循环的情况进行集成作为读者的练习。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于在链表中查找结点的生产代码 的相关文章

随机推荐

  • 在 Hibernate 中创建 UPDATE RETURNING 查询

    在 Oracle 中 我们可以创建一个更新查询 该查询将使用 RETURNING 子句返回更新的记录 Hibernate中有类似的功能吗 除了数据库生成的值之外 Hibernate 显然不需要返回更新的实例 因为对象传递给Session s
  • 动态字段取决于 WTForms 的先前字段

    我正在使用 WTForms 制作表格 目前 我有这个 class UploadForm flask wtf Form fichier wtforms fields FileField u Fichier description wtform
  • 相对于变换元素的绝对定位元素位置

    我重新创建了我在模板中遇到的问题 有一个nav具有position relative 在 的里面nav有一个div有两个嵌套列表 其中一个列表的位置绝对固定在列表的底部nav 当div对其应用了变换 当 的时候div在绝对和相对定位的元素之
  • 请求超级用户权限编辑文件

    我正在规划一个需要编辑系统文件的应用程序 我只能使用 root 权限编辑该文件 我有一个已 root 且安装了 Superuser apk 的开发手机 其他需要 root 的应用程序会在首次启动时请求 root 访问权限 我想做同样的事情
  • Intel 上的 gcc 中的 _mm_pause 用法

    我参考过这个网页 https software intel com en us articles benefitting power and performance sleep loops https software intel com
  • 如果 Row1 = 值 1,则更新其他行

    我有一个小的 php 脚本 用于访问 mySql 数据库 我想在数据库中插入新记录之前查看该数字 值 1 是否等于数据库中的记录 这也在第 1 行 所以我想 查看传入的电话号码是否等于数据库中的电话号码 如果是这样 则必须保持电话号码相同的
  • rightBarButtonItem 信息按钮,右侧没有空格

    我有一个UIViewController设置为在其右侧显示一个信息按钮UINavigationItem像这样 UIButton infoButton UIButton buttonWithType UIButtonTypeInfoLight
  • 异常行为

    我是 C 的新手 小代码示例如下 int main int argc char argv char ch1 int int1 cin gt gt ch1 cin gt gt int1 cout lt lt ch1 lt lt n cout
  • 如何在CloudFormation模板中描述AWS Lambda函数测试事件?

    我在 CloudFormation 模板中描述了现有的 AWS Lambda 函数 然后我面临下一个问题 在我们的 Lambda 中 我们配置了一些测试事件 这有助于我们验证一些用例 我的意思是下面屏幕截图中的功能 但我没有看到任何将这些测
  • Python3将模块从文件夹导入到另一个文件夹

    我的结构字典是 mainFolder folder1 init py file1 py file2 py folder2 init py file3 py file4 py setup py init py 我需要将 file4 py 从f
  • 在打印 CSS 上在每个页面周围绘制边框?

    打印时我需要在每个页面周围绘制边框 我最初是使用带有分页符的 div 来完成此操作 例如 media print contentContainer position inline height 98 width 100 top 0px le
  • 是否可以从另一个方法传递 args[] 来调用 main 方法?

    我试图从另一个传递参数的方法调用类的主要方法 就像从命令行运行该类时一样 有没有办法做到这一点 您可以致电main方法就像您调用任何其他 静态 方法一样 MyClass main new String arg1 arg2 arg3 Exam
  • 可升级读锁的优点?

    我想知道使用可升级读锁与执行这些步骤相比有什么优势 获取读锁 检查条件以查看是否需要进行写锁定 释放读锁 采取写锁定 执行更新 释放写锁 与获取可升级读锁相比 执行上述步骤的一个明显缺点是 步骤 3 和步骤 4 之间存在一个时间窗口 其中另
  • 自动检测内部/外部开发环境

    我们使用以下函数来自动检测我们是在内部机器上还是在实时服务器上 然后为各种组件选择适当的配置 function devIsLocal res false http host SERVER HTTP HOST if http host loc
  • 根据条件延迟 Celery 任务

    有什么办法可以根据条件延迟 Celery 任务的运行吗 在它从计划变为活动之前 我想执行快速检查 看看我的机器是否可以根据提供的参数和当时机器的状态运行该任务 如果不是 它会暂停计划队列并等待 直到满足条件 我环顾了以下几点 但似乎没有解决
  • 如果浏览器在 asp .net 中关闭,请从浏览器中注销?

    我的要求有点复杂 用户正在使用 Web 浏览器访问数据库 而在访问数据库时 如果用户关闭活动页面而不是注销会话 该会话需要自动注销 有人可以指导我如何做这个吗 我在母版页中使用了jquery onbeforeunload 我收到消息离开页面
  • 有没有办法监控页面上运行的 JavaScript 函数?

    有没有办法查看页面上正在执行哪些功能 如果我在页面上加载外部脚本 是否可以动态更改函数的功能或阻止其运行 HTML5 http www w3 org TR html5 scripting 1 html establish script bl
  • Python 内置对象的 __enter__() 和 __exit__() 在哪里定义?

    我读到每次使用 with 时都会调用该对象的 enter 和 exit 方法 我知道对于用户定义的对象 您可以自己定义这些方法 但我不明白这对于 打开 等内置对象 函数甚至测试用例是如何工作的 这段代码按预期工作 我假设它使用 exit 关
  • 有没有一种从 unsigned char* 转换为 char* 的好方法?

    那些天我读了很多关于reinterpret cast lt gt 以及应该如何使用它 并在大多数情况下避免使用它 虽然我明白使用reinterpret cast lt gt 投射自 说unsigned char to char is 实施定
  • 用于在链表中查找结点的生产代码

    我在一次采访中被问到这个问题 我被要求编写代码 用于在 O 1 空间和线性时间的生产环境中在链表 其形式为 Y 形式 双臂不一定相等 中查找结点 我想出了这个解决方案 我以前在某处见过 1 Measure lengths of both l