相交的链表
下面的代码尝试解决带环和不带环的链表是否相交以及如果相交,交点的位置两个问题。见编程之美3.6节,代码应当同时解决了后面的两个扩展问题。
Node* commonEnd(Node* a, Node* b) {
if (!a || !b) return 0;
Node *p1 = a, *p2 = a;
do {
if (p2->next) p2 = p2->next;
if (p2->next) p2 = p2->next;
if (p1->next) p1 = p1->next;
} while (p1 != p2);
Node *q1 = b, *q2 = b;
do {
if (q2 == p1) return p1;
if (q2->next) q2 = q2->next;
if (q2 == p1) return p1;
if (q2->next) q2 = q2->next;
if (q1->next) q1 = q1->next;
} while (q1 != q2);
return 0;
}
int distance(Node* a, Node* b) {
if (a && b) {
if (a == b) return 0;
Node* p1 = a, *p2 = a;
int d = 0;
do {
if (p2->next) p2 = p2->next, ++d;
if (p2 == b) return d;
if (p2->next) p2 = p2->next, ++d;
if (p2 == b) return d;
if (p1->next) p1 = p1->next;
} while (p1 != p2);
}
return -1;
}
Node* step(Node* a, int n) {
while (n-- && a) a = a->next;
return a;
}
Node* intersection(Node* a, Node* b) {
Node* end = commonEnd(a, b);
if (!end) return 0;
int da = distance(a, end), db = distance(b, end);
if (da > db) a = step(a, da - db);
else b = step(b, db - da);
while (a != b) a = a->next, b = b->next;
return a;
}