鏈表
單鏈表 雙鏈表 循環鏈表
鏈表_stl-CSDN博客
虛擬頭結點
反轉鏈表
刪除鏈表元素
方法一: 直接使用原來的鏈表來進行刪除操作。
頭節點是否為空
頭鏈表的值是否為要刪除的值
頭結點刪除后,新的頭節點是否依舊要刪除 ,刪除后的,新頭節點可能是空結點
方法二: 設置一個虛擬頭結點在進行刪除操作。
ListNode* dummyHead = new ListNode(0); // 設置一個虛擬頭結點dummyHead->next = head; // 將虛擬頭結點指向head,這樣方便后面做刪除操作ListNode* cur = dummyHead;while (cur->next != NULL) {if(cur->next->val == val) {ListNode* tmp = cur->next;cur->next = cur->next->next;delete tmp;} else {cur = cur->next;}}head = dummyHead->next;delete dummyHead;return head;}
設置一個虛擬頭結點,這樣原鏈表的所有節點就都可以按照統一的方式進行移除
203. 移除鏈表元素 - 力扣(LeetCode)
// 危險操作!
1.直接操作原始頭指針
2.造成空指針解引用 (先訪問
head->val會觸發尸變)
3.需要確保在刪除節點后立即更新指針,避免懸空指針的使用
反轉鏈表
206. 反轉鏈表 - 力扣(LeetCode)
class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode*cur=head;ListNode*pre=nullptr;ListNode*next;while(cur){next=cur->next;cur->next=pre;pre=cur;cur=next;}return pre;}
};
遞歸
( 從后往前翻轉指針指向 )
ListNode* reverseList(ListNode* head) {// 遞歸終止條件if (!head || !head->next) {return head;}ListNode* reversedHead = reverseList(head->next);head->next->next = head;head->next = nullptr;return reversedHead;}
快慢指針 刪除鏈表的倒數第N個節點
思想
如果要刪除倒數第n個節點,讓fast移動n+1步,然后讓fast和slow同時移動,直到fast指向鏈表末尾。刪掉slow所指向的節點就可以了
為什么是n+1呢,因為只有這樣同時移動的時候slow才能指向刪除節點的上一個節點(方便做刪除操作)
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode*dummy=new ListNode(0);dummy->next=head;ListNode*fast=dummy;ListNode*slow=dummy;for(int i=0;i<n+1;i++){fast=fast->next;}while(fast){slow=slow->next;fast=fast->next;}ListNode*temp=slow->next;slow->next=temp->next;delete temp;return dummy->next;}
};
19. 刪除鏈表的倒數第 N 個結點 - 力扣(LeetCode)
鏈表相交
簡單來說,就是求兩個鏈表交點節點的指針
class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode*currentA=headA;ListNode*currentB=headB;int lenA=0,lenB=0;while(currentA){currentA=currentA->next;lenA++;}while(currentB){currentB=currentB->next;lenB++;}currentA=headA;currentB=headB;if(lenA>lenB){int len=lenA-lenB;while(len--){currentA=currentA->next;}}if(lenA<lenB){int len=lenB-lenA;while(len--){currentB=currentB->next;}}while(currentA!=currentB){currentB=currentB->next; currentA=currentA->next;}return currentA;}
};
面試題 02.07. 鏈表相交 - 力扣(LeetCode)
環形鏈表II
fast走兩步,slow走一步,相對于slow來說,fast是一個節點一個節點的靠近slow的,所以fast一定可以和slow重合
在相遇節點處,定義一個指針index1,在頭結點處定一個指針index2。
讓index1和index2同時移動,每次移動一個節點, 那么他們相遇的地方就是 環形入口的節點
(x + y) * 2 = x + y + n (y + z)
x + y = n (y + z)
x = n (y + z) - y
x = (n - 1) (y + z) + z
當 n為1的時候,公式就化解為 x = z
這就意味著,從頭結點出發一個指針,從相遇節點 也出發一個指針,這兩個指針每次只走一個節點, 那么當這兩個指針相遇的時候就是 環形入口的節點
class Solution {
public:ListNode *detectCycle(ListNode *head) {ListNode*show=head;ListNode*fast=head;while(fast != NULL && fast->next != NULL){show=show->next;for(int i=0;i<2;i++)fast=fast->next;if(show==fast){ListNode*index1=head;ListNode*index2=fast;while(index1!=index2){index1=index1->next;index2=index2->next;}return index1;}}return nullptr;}
};
142. 環形鏈表 II - 力扣(LeetCode)