昨天没刷题,今天也只刷了一个。希望继续坚持下去!11.28
今天的题目是
JZ52 两个链表的第一个公共结点
题目链接
题目的大义是给两个链表,要求出第一个公共节点。
我为啥把“第一个公共节点标红呢”,因为是我第一次提交的时候没想明白,把第一个公共节点想成了第一个相等的点。
然后就会这样:
大概就是题目要求的并不是第一个值相等的那个节点,而是要求某个节点,这个节点之后这两个串相等直到结束。
解题思路:(我的思路比较简单也比较暴力) 时间复杂度O(nm)
- 相当于两个for遍历这两个串,拿第一个串中间的每个字去匹配第二个串中间的字
- 如果找到某个字开始这两个串之后的内容一模一样(这个是写了CheckLast辅助函数实现的),就把后面的内容衔接在我新建的链表上返回
上代码:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
bool checkLast(ListNode* p1,ListNode* p2){ //辅助函数,用来检查是不是p1和p2指针以及之后的内容是不是一一对应的
while(p1&&p2){ //p1、p2都没到最后一个元素就能进入循环
if(p1->val!=p2->val) return false; //如果指向的节点val不相等就返回false
p1=p1->next;p2=p2->next; //均向后面移动一个节点
}
if(p1==nullptr&&p2==nullptr){ //如果一一比对最后都指向了自己串的尾部,就认为这两个串的后半部分是相等的
return true;
}
return false; //如果还有其他情况(一长一短)就返回false
}
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* root = new ListNode(-1); //用来存放结果的新建链表
ListNode* h1 = root; //这两行和我上一篇博客一模一样
ListNode* h2 = pHead2; //用来记录第二个链表的首部,要不然循环一次回不到链表开头了
while(pHead1){ //遍历p1
while(pHead2){ //遍历p2
if(checkLast(pHead1,pHead2)){ //如果这个节点开始之后全都想等
while(pHead1){ //就把p1链表的内容全部插入到新建的链表root后面
h1->next = pHead1;
h1 = h1->next;
pHead1 = pHead1->next;
}
return root->next; //找到了这个公共串,返回
}else{
pHead2 = pHead2->next; //没找到的话就把p2往后面移动一步
}
}
pHead2 = h2; //此时p2循环了一轮,把p2的指针重新移动回开头
pHead1 = pHead1->next; //p1往后面走一步
}
return root->next; //如果没有在上面return说明找不到这个节点,这里return的是一个空链表
}
};