点:边界细心处理,栈运用
题意:两个链表相交,求交点
剑指offer面试题37
思路:首先也说一下如何判断两个链表是否相交这是个普通常见题:看他们的尾节点是不是一个。
快速找交点,用栈,当然需要O(M+N)的空间复杂度,即两个栈分别保存两个链表的全部节点地址,既然是相交的,那么从相交节点到尾节点一直都会是同一个节点,利用栈特点,两个链表全部节点分别入栈后,两个栈同步的出栈,直到发现第一个不一样的节点,说明上一个节点就是两个链表的交点
代码:
#include <iostream>
#include <random>
#include <stack>
template<class T> struct Node {
T val;
Node<T> *next;
Node(T _val):val(_val), next(nullptr) {}
};
template<class T> class Slist {
Node<T> *root;
public:
Slist():root(nullptr) {}
~Slist() {
Node<T> *cur = root;
while (cur) {
Node<T> *next = cur->next;
delete cur;
cur = next;
}
}
Node<T> *GetRoot () {
return root;
}
void Add (int val) {
if (!root) {
root = new Node<T>(val);
} else {
Node<T> *cur = root;
while (cur) {
if (cur->next) {
cur = cur->next;
} else {
break;
}
}
Node<T> *newnode = new Node<T>(val);
cur->next = newnode;
}
}
void show () {
if (root) {
Node<T> *cur = root;
while (cur) {
std::cout << cur->val << "\t";
cur = cur->next;
}
std::cout << std::endl;
}
}
Node<T> *Get_Last_K (int k) {
Node<T> *cur1 = root, *cur2 = root;
while (k--) {
if (!cur1->next) {
return nullptr;
}
cur1 = cur1->next;
}
if (!cur1) {
return cur2;
}
while (cur1) {
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur2;
}
void Adds (Node<T> *other) {
Node<T> *cur = root;
while (cur) {
if (cur->next) {
cur = cur->next;
} else {
cur->next = other;
break;
}
}
}
};
int main () {
std::random_device rd;
Slist<int> sl1, sl2;
for (int i = 0; i < 20; i++) {
sl1.Add(rd() % 100);
}
Node<int> *last_5 = sl1.Get_Last_K(5);
if (last_5) {
for (int i = 0; i < 10; i++) {
sl2.Add(rd() % 100);
}
sl2.Adds(last_5);
}
std::stack<Node<int> *> stk1, stk2;
Node<int> *s1 = sl1.GetRoot(), *s2 = sl2.GetRoot();
while (s1) {
stk1.push(s1);
s1 = s1->next;
}
while (s2) {
stk2.push(s2);
s2 = s2->next;
}
int val;
while (!stk1.empty() && !stk2.empty()) {
if (stk1.top() == stk2.top()) {
val = stk1.top()->val;
stk1.pop();
stk2.pop();
} else {
break;
}
}
sl1.show();
sl2.show();
std::cout << val << std::endl;
return 0;
}