-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathintersection.cpp
117 lines (104 loc) · 3.75 KB
/
intersection.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
Given two (singly) linked lists, determine if the two intersect.
Return the intersecting node. Note that the intersection is defined based on reference,
not value. That is, if the kth node of the first linked list is the exact same node (by reference),
as the jth node of the second linked list, then they are intersecting.
*/
#include <cstddef>
#include <iostream>
#include <type_traits>
#include <cmath>
struct Node {
Node* next;
size_t idx;
};
struct Bubble {
size_t pos;
bool left;
};
bool getNewHeads(const Node* const leftCurr, const Node* const rightCurr, const Node** const leftHead, const Node** const rightHead, Bubble& bubble, const size_t leftCurrPos = 0, const size_t rightCurrPos = 0) {
if (leftCurr == nullptr || rightCurr == nullptr) {
return false;
}
const Node* leftNext, *rightNext;
size_t leftNextPos, rightNextPos;
if (leftCurr->next != nullptr) {
leftNext = leftCurr->next;
leftNextPos = leftCurrPos + 1;
}
else {
leftNext = leftCurr;
leftNextPos = leftCurrPos;
}
if (rightCurr->next != nullptr) {
rightNext = rightCurr->next;
rightNextPos = rightCurrPos + 1;
}
else {
rightNext = rightCurr;
rightNextPos = rightCurrPos;
}
if (leftCurr->next == nullptr && rightCurr->next == nullptr) {
if (leftCurr != rightCurr)
return false;
bubble.pos = abs(leftCurrPos - rightCurrPos);
bubble.left = leftCurrPos > rightCurrPos;
return true;
}
if (!getNewHeads(leftNext, rightNext, leftHead, rightHead, bubble, leftNextPos, rightNextPos)) {
return false;
}
if (bubble.left) {
if (bubble.pos == leftCurrPos) {
*leftHead = leftCurr;
}
if (rightCurrPos == 0) {
*rightHead = rightCurr;
}
}
else {
if (bubble.pos == rightCurrPos) {
*rightHead = rightCurr;
}
if (leftCurrPos == 0) {
*leftHead = leftCurr;
}
}
return true;
}
bool getNewHeads(const Node* const leftCurr, const Node* const rightCurr, const Node** const newLeftHead, const Node** newRightHead) {
Bubble bubble;
return getNewHeads(leftCurr, rightCurr, newLeftHead, newRightHead, bubble);
}
const Node* findEqual(const Node* leftCurr, const Node* rightCurr) {
if (leftCurr == rightCurr) {
return leftCurr;
}
return findEqual(leftCurr->next, rightCurr->next);
}
bool intersect(const Node* const leftHead, const Node* const rightHead, const Node** const intersection) {
const Node* newLeftHead, *newRightHead;
if (!getNewHeads(leftHead, rightHead, &newLeftHead, &newRightHead)) {
return false;
}
*intersection = findEqual(newLeftHead, newRightHead);
return true;
}
int main() {
Node n[9];
for (size_t i = 0; i < std::extent<decltype(n)>::value; ++i) {
n[i].idx = i;
n[i].next = nullptr;
}
for (size_t i = 0; i < 6; ++i) {
n[i].next = &n[i + 1];
}
n[7].next = &n[3];
const Node* intersection;
std::cout << "intersect(n0, n7) = " << (intersect(&n[0], &n[7], &intersection) ? std::to_string(intersection->idx) : "null") << std::endl;
std::cout << "intersect(n2, n7) = " << (intersect(&n[2], &n[7], &intersection) ? std::to_string(intersection->idx) : "null") << std::endl;
std::cout << "intersect(n3, n7) = " << (intersect(&n[3], &n[7], &intersection) ? std::to_string(intersection->idx) : "null") << std::endl;
std::cout << "intersect(n0, n0) = " << (intersect(&n[0], &n[0], &intersection) ? std::to_string(intersection->idx) : "null") << std::endl;
std::cout << "intersect(n0, n8) = " << (intersect(&n[0], &n[8], &intersection) ? std::to_string(intersection->idx) : "null") << std::endl;
return 0;
}