2021-1-19 刪除結點 找第一個公共結點
阿新 • • 發佈:2021-02-04
技術標籤:2021年1月
題目1 刪除連結串列中等於給定值 val 的所有節點。
x
示例:
輸入: 1->2->6->3->4->5->6, val = 6
輸出: 1->2->3->4->5
解1
常規方法,遍歷連結串列,檢視要刪除的結點
注意!
遍歷時,因為連結串列遍歷指標無法返回,所以要以遍歷結點的下一個值和刪除值進行判斷,便於刪除
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//1. 定義一個標記結點,指向頭,並將頭節點也賦值給該節點
ListNode* pTemp = new ListNode;
pTemp->next = head;
head = pTemp;、
//2. 遍歷連結串列,遇到刪除節點,則修改指標指向的內容
while(pTemp->next)
{
if(pTemp->next->val == val)
pTemp->next = pTemp->next->next;
else
pTemp = pTemp->next;
}
//3. 返回頭節點
return head->next;
}
};
解2
遞迴演算法,遞迴遍歷每個幾點,將遞迴返回值拼接到上一次遞迴的節點後面。
- 正常應該返回原結點即可;
- 若遇到刪除節點,則將刪除結點的下一個拼接到上一個結點
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(head)
{
//如果未遞迴到頭,繼續深入
head- >next = removeElements(head->next,val);
}
//head的為NULL,開始返回
//返回過程中,遇到刪除結點
if(head && val == head->val)
//該節點下一個返回個上一節點(即刪除了該節點)
return head->next;
//正常返回本結點即可
return head;
}
};
題目2 輸入兩個連結串列,找出它們的第一個公共節點。
如下面的兩個連結串列:
在節點 c1 開始相交。
解1 雙指標法
假設:
連結串列1長度:l1+C;連結串列2長度:l2+C;
兩個指標headA、headB分別遍歷連結串列L1,L2
當headA走到NULL時,重新賦值L2頭部,繼續遍歷;
當headB走到NULL時,重新賦值L1頭部,繼續遍歷;
當兩個連結串列走到第一個公共結點,都走l1+l2+C的長度,走的長度相同。
特殊情況
- 若有一個連結串列為NULL,則無交點
- 如下程式碼中,若兩個連結串列無交點,會進入死迴圈。通過記錄兩個連結串列最後一個結點,判斷是否相同,判斷兩連結串列有無交點
- 若兩個連結串列長度相同且有公共節點,同時走到最後的NULL,雖然兩指標相同,但是並非公共節點,需要繼續遍歷。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//1. 如果有一個連結串列為NULL,則無交點
if(headA == NULL || headB == NULL)
return NULL;
//標記兩個連結串列頭
ListNode* pA = headA;
ListNode* pB = headB;
//標記兩個連結串列尾
ListNode* lA = NULL;
ListNode* lB = NULL;
//雙指標迴圈遍歷
while((headA == NULL && headB == NULL) || headA != headB)
{
//遍歷到尾結點
if(headA && headA->next == NULL)
lA = headA;
if(headB && headB->next == NULL)
lB = headB;
//2. 如果兩個連結串列尾都不同,則無交點
if(lA && lB && lA!=lB)
return NULL;
//3. 迴圈遍歷
headA == NULL ? headA = pB : headA = headA->next;
headB == NULL ? headB = pA : headB = headB->next;
}
return headA;
}
};
解2
設定容器<ListNode*,int>,先遍歷第一個連結串列,將每個結點對應值1;再遍歷第二個連結串列,若遍歷到的結點在容器中存在,返回該節點。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//==================容器法=============================
map<ListNode*,int> nodes;
while(headA)
{
nodes[headA] = 1;
headA = headA->next;
}
while(headB)
{
if(nodes[headB])
return headB;
headB = headB->next;
}
return NULL;
}
};
解3 快慢指標
- 先求兩個連結串列長度,假設相差k個元素。
- 再遍歷連結串列,長連結串列指標先走k步,然後兩個連結串列遍歷指標一起移動,知道結點相同