移除單鏈表中指定位置的節點
阿新 • • 發佈:2021-12-14
題目描述
給定一個連結串列,刪除連結串列的倒數第 nn 個節點,並且返回連結串列的頭結點。
示例1
輸入:head = [1,2,3,4,5], n = 2
輸出:[1,2,3,5]
輸入:head[1], n=1
輸出:[]
輸入:head = [1,2], n = 1
輸出:[1]
進階要求
嘗試用一趟掃描實現
演算法1
兩次遍歷
- 第一次遍歷求出連結串列長度
- 第二次遍歷刪掉指定的結點
- 注意刪掉頭結點的特殊情況(這個自己沒有考慮到,當提交調錯的時候才解決掉這個問題)
時間複雜度
遍歷兩次連結串列,空間複雜度為O(L)
空間複雜度
僅需要定義常數個指標變數,故時間複雜度為O(1)
程式碼
class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { int sum = 0; ListNode* a = head; // 求一下連結串列的長度 while (a) { ++sum; a = a->next; } // 判斷刪掉第一個節點的特殊情況 if (sum == n) { head = head->next; return head; } ListNode* b = head; // 遍歷刪掉指定的節點 for (int i = 0; i < sum - n - 1; i++) { head = head->next; } head->next = head->next->next; return b; } };
演算法2
一次遍歷
1.在頭部之前新增保護點
2.設定兩個指標first和second,均指向保護節點
3.first指標先向後移動n + 1個結點
4.然後first和second指標同時向後移動,直到first指標指向空,此時second結點指向的下一個結點需要刪除
原理
始終保持兩個指標之間間隔n個結點,在first到達終點時,second的下一個結點就是從結尾數第n個結點。
時間複雜度
遍歷兩次連結串列,空間複雜度為O(L)
空間複雜度
僅需要定義常數個指標變數,故時間複雜度為O(1)
class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* e_head = new ListNode(0); e_head->next = head; ListNode* first = e_head; ListNode* second = e_head; n++; while (n--) { first = first->next; } while (first) { first = first->next; second = second->next; } second->next = second->next->next; return e_head->next; } };