Production code for finding junction in a linked list

爷,独闯天下 提交于 2019-12-03 17:45:56

The problem is made difficult by the interviewer's (seeming) interpretation that the following shapes are also considered valid:

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

i.e. there is a junction but then the list loops back to a place either before or after the junction. The procedure of calculating the length of the list does not help directly because the length of a cyclic list is not defined.

First note that the length of a loop at end of a cyclic list can be calculated by this O(1) memory / O(n) time procedure:

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;
  }
}

For example, consider the cyclic list

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

The algorithm works as follows (T=tortoise, H=hare):

       /--------\
 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

Now if there are X nodes before the node that forms the junction point for the cycle (in the example node (3)), i.e. X=2, and the cycle consists of C nodes (in the example C=4), when the tortoise enters the junction point for the first time after X steps the hare is in the cycle at location (2X - X) % C, i.e. (X % C) (in the example, tortoise enters (3) after 2 steps 3nd hare is then at location L = (2 % 4 = 2), i.e. in node (5) (the index is zero-based). It will now take (C-L-1) steps for the hare to reach the tortoise (1 step in the example) as the hare has an 'advantage' of L steps; this means that the number of steps for the algorithm until the hare meets the tortoise the first time is

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

C is known (it's calculated by the algorithm), and the total number of steps (denote by S) can be calculated, i.e. we have

  S + 1 - C = X - X % C

Suppose now that the hare as an extra advantage of Q steps, i.e. hare takes first Q next pointers forwards before the algorithm starts; then when the tortoise enters the junction point the hare is at location ((X + Q) % C), and we get

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

This gives now a procedure to calculate the difference in the length of the paths from 'A' and 'B' to the common junction point P (denote the lengths a and b and their difference thus a-b) (assume a > b without loss of generality).

First run the algorithm from starting point A, calculate cycle length C and store number of steps S_A. Then run it so that the tortoise starts at A and the hare at B and calculate the number of steps S_X. This means that the hare has now an advantage of (a-b) nodes, i.e.

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

Thus

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

I.e. the difference gives the length difference modulo C; to calculate the length difference's quotient by C run the algorithm usually from starting point B, getting number of steps S_B, i.e. all together

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

subtract the first two equations to get

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

the term in square brackets is in ]-C,+C[ , so

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

in this interval there are at most two differences which equal (S - S_X) modulo C; use them both to try to spot the junction point---problem solved.

Example:

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

In the calculation of S_A, the hare and tortoise meet after 3 steps at (5) and cycle length 3 is returned. In the calculation of S_B, the hare and tortoise meet after 3 steps at (6) and cycle length 3 is returned. For S_X, hare enters at B and tortoise at A; they meet after 2 steps at (4). This gives

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

i.e. the length difference between (a - b) is 1 modulo 3; this gives possible length differences { -2, +1 }; -2 is disregarded by assumption a > b, so we get a = b + 1. Then the junction point is found by traversing first +1 node from A forwards to (2), and then advancing from both arms at the same pace until the junction point is found.

Integration with the cases where there are non-shared loops and/or no loops left as an exercise to the reader.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!