(1)两个链表的第一个公共结点
字节跳动的HR人真的很好 和蔼可亲 就像傅姓洲洲学长一样 人超好 给我出的题很简单,,可惜我 面字节一点没准备 怕是一年多没写代码 我连这个都没写出来 我人傻了 我是飞舞
首先是比较常规的写法.我们维护一个map,然后遍历一下这俩链表 ,找见相同的就返回好咯.
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
map<ListNode*,int>m;
while(pHead1||pHead2)
{
if(pHead1){
if(m.find(pHead1)!=m.end()){return pHead1;}
else{
m.insert(make_pair(pHead1,1));
}
pHead1=pHead1->next;
}
if(pHead2){
if(m.find(pHead2)!=m.end()){return pHead2;}
else{
m.insert(make_pair(pHead2,1));
}
pHead2=pHead2->next;
}
}
return NULL;
}
};
然后hr小哥又问 你能不能别靠map ,我说 我行!当我不行的时候我就站到行人道上 这样我就变成了行人
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1==NULL||pHead2==NULL)return NULL;
ListNode * p1,*p2;
p1=pHead1;p2=pHead2;
while(p1&&p2&&p1!=p2)
{
p1=p1->next;
p2=p2->next;
if(p1==p2)return p1;
if(p1==NULL)p1=pHead2;
if(p2==NULL)p2=pHead1;
}
return p1;
}
};
(2)链表中环的入口节点....捂脸.我第一次面试的时候,剑指刷的只剩了这个题,然后他就考了......有时候就是这么点背.......但是主要还是怪自己菜 真的飞舞
首先是比较好想的办法.写一个map,然后往里存节点.扫一遍就能找到如果有环.环的开始节点.
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead==NULL)return NULL;
ListNode * p1=pHead;
map<ListNode* ,int>m;
while(p1)
{
if(m.find(p1)!=m.end())return p1;
m.insert(make_pair(p1,1));
p1=p1->next;
}
return NULL;
}
};
这时候...我不等你说了 不用map是吧?
那可以循环.找有没有环,找环的长度,然后快慢指针直接求环的开始节点.
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead==NULL||pHead->next==NULL)return NULL;
ListNode * p1,*p2;
p1=p2=pHead;
while(p1&&p2&&p2->next)
{
p1=p1->next;
p2=p2->next->next;
if(p1==p2)break;
}
if(p1==NULL||p2==NULL)return NULL;
int len=1;
p1=p1->next;
while(p1!=p2)
{
p1=p1->next;len++;
}
p1=p2=pHead;
while(len--)
{
p2=p2->next;
}
while(p1&&p2&&p1!=p2)
{
p1=p1->next;p2=p2->next;
}
return p1;
}
};
(3)删除列表中重复的节点
注意审题,,不是保留一个 ,,是重复的都删掉.
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(!pHead||!pHead->next)return pHead;
ListNode * p=pHead;
ListNode * ans=new ListNode(0);
ans->next=pHead;
ListNode * last=ans;
while(p&&p->next)
{
if(p->val==p->next->val)
{
while(p&&p->next&&p->val==p->next->val)
{
p=p->next;
}
p=p->next;
last->next=p;
}
else
{
last=p;
p=p->next;
}
}
return ans->next;
}
};
这里写来写去到处越界,索性不要考虑哪里需不需要写判空的条件,直接都写上就老了.因为有可能这个链表就是一个222这种 所以先整一个新的头结点指向链表头,再做删重的操作.
看见题解里有递归写法...我总感觉这题写递归更难想........咱也贴一个递归的写法好了.
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(!pHead||!pHead->next)return pHead;
ListNode * p=pHead;
if(p&&p->next&&p->val==p->next->val)
{
while((p&&p->next&&p->val==p->next->val))
p=p->next;
return deleteDuplication(p->next);
}
else
{
p->next=deleteDuplication(p->next);
return p;
}
return pHead;
}
};
链表就到这里,下一篇写二叉树