题目描述
输入两个链表,找出它们的第一个公共结点。
思想: 先比较两个链表的长度, 让得出差值, 让长的先走长出的节点数目, 然后两个链表一起走, 有相同节点时, 指向链表的游标会碰在一起, 此时游标就是返回值, 时间复杂度O(m+n)?
class Solution {
public:
unsigned int getLength(ListNode *node) {
ListNode *ct = node;
unsigned int count = 0;
while (nullptr != ct) {
count++;
ct = ct->next;
}
return count;
}
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
unsigned int len1 = getLength(pHead1);
unsigned int len2 = getLength(pHead2);
int len = len1 - len2;
ListNode *ctNode1 = pHead1;
ListNode *ctNode2 = pHead2;
if (0 < len) {
for (int i = 0; i < len; i++) {
ctNode1 = ctNode1->next;
}
}
else {
for (int i = 0; i < -len; i++) {
ctNode2 = ctNode2->next;
}
}
while ((ctNode1 != ctNode2) && (nullptr != ctNode1) && (nullptr != ctNode2)) {
ctNode1 = ctNode1->next;
ctNode2 = ctNode2->next;
}
return ctNode1;
}
};
利用栈, 先把两个序列分别压入两个栈中, 然后再依次弹出, 直至不同元素时返回, vs上测试通过, 牛客提交有问题
class Solution {
public:
ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
stack<ListNode *> sk1;
stack<ListNode *> sk2;
ListNode *ct1 = pHead1;
ListNode *ct2 = pHead2;
ListNode *ret = nullptr;
while (nullptr != ct1) {
sk1.push(ct1);
ct1 = ct1->next;
}
while (nullptr != ct2) {
sk2.push(ct2);
ct2 = ct2->next;
}
while (sk1.top() == sk2.top()) {
ret = sk1.top();
sk1.pop();
sk2.pop();
}
return ret;
}
};
暴力法, 以此内外层循环, 注意, 第二个while循环后要把游标置于开头位置(我忘了:(
), 时间复杂度O(mn)
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if (nullptr == pHead1 || nullptr == pHead2) {
return nullptr;
}
ListNode *ctList1 = pHead1;
ListNode *ctList2 = pHead2;
while (nullptr != ctList1) {
while (nullptr != ctList2) {
if (ctList1->val == ctList2->val)
return ctList1;
ctList2 = ctList2->next;
}
ctList2 = pHead2;
ctList1 = ctList1->next;
}
return nullptr;
}
};
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/