判断两条链表是否交叉,若有交叉,返回交叉节点的指针。
作者:互联网
上周面试挂了,反思原因,莫非是因为一道算法题没做好吗?这题目是“判断两条链表是否交叉,若有交叉,返回交叉节点的指针。” 为了防止反复在同一个阴沟里翻船,决定把最优解写出来。
#include "pch.h"
#include <iostream>
template<typename T>
class List {
public:
struct Node {
T data;
Node* next;
Node(T& d, Node* ntx = nullptr) : data(d), next(ntx) {}
};
Node* mHead = nullptr;
public:
//List(){}
~List() {
Node* pcur = mHead, *pnext = nullptr;
while (pcur) {
pnext = pcur->next;
delete pcur;
pcur = pnext;
}
}
bool AddNode(T dt, bool attail = true) {
Node*ptr = new Node(dt);
return AddNode(ptr, attail);
}
bool AddNode(Node* nd, bool attail = true) {
if (nd) {
if (attail) {
Node* ptail = Tail();
if (ptail) {
ptail->next = nd;
}
else {
mHead = nd;
}
}
else {
nd->next = mHead;
mHead = nd;
}
return true;
}
return false;
}
Node* Intersect(List& oth) {
Node* lptr = nullptr, *sptr = nullptr;
{
const int sz1 = Size();
const int sz2 = oth.Size();
int num = 0;
if (sz1 >= sz2) {
lptr = mHead;
sptr = oth.mHead;
num = sz1 - sz2;
}
else {
lptr = oth.mHead;
sptr = mHead;
num = sz1 - sz2;
}
for (int i = 0; i < num; ++i) {
if (lptr) {
lptr = lptr->next;
}
}
}
while (lptr && sptr) {
if (lptr == sptr) {
return lptr;
}
lptr = lptr->next;
sptr = sptr->next;
}
return nullptr;
}
private:
Node* Tail() {
Node* ptr = mHead;
while (ptr && ptr->next) {
ptr = ptr->next;
}
return ptr;
}
int Size() {
int sz = 0;
Node* ptr = mHead;
while (ptr) {
++sz;
ptr = ptr->next;
}
return sz;
}
};
int main()
{
std::cout << "Hello World!\n";
List<int> list1, list2;
for (int i = 1; i < 3; ++i) {
list1.AddNode(i);
}
for (int i = 25; i < 28; ++i) {
list2.AddNode(i);
}
#if 1
for (int i = 100; i < 101; ++i) {
List<int>::Node* node = new List<int>::Node(i);
list1.AddNode(node);
list2.AddNode(node);
}
#endif
auto ptr = list1.Intersect(list2);
if (ptr) {
std::cout << "intersect point at " << ptr << std::endl;
}
else {
std::cout << "no intersection\n";
}
return 0;
}
代码创建了两条有交叉节点的链表。如图所示:
程序运行结束时,析构这两条链表,发生错误,是因为交叉节点被两次释放:
标签:Node,交叉,int,mHead,lptr,next,链表,ptr,指针 来源: https://blog.51cto.com/frankniefaquan/2378379