(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;
}
};
鏈表就到這裏,下一篇寫二叉樹