Lintcode 在O(1)時間複雜度刪除連結串列節點
1.描述
給定一個單鏈表中的一個等待被刪除的節點(非表頭或表尾)。請在在O(1)時間複雜度刪除該連結串列節點。
樣例
給定 1->2->3->4
,和節點 3
,刪除 3 之後,連結串列應該變為 1->2->4
。
2.分析
按照一般的思路,刪除一個節點node首先需要找到他所在的位置,讓node的上一個節點直接指向node的下一個節點,
空過node,也就是讓node->perior的next指向node->next,但這樣做首先需要知道node->perior(這在單鏈表中不好實現),
並且這樣做是o(n)的演算法,題目要求為o(1)時間複雜度。在上面的分析中,我們發現只要讓node的下一個節點取代node的位置
就相當於空過了node讓node的前一個節點指向後一個節點,因此有了最簡單的一句程式碼*node=*(node->next);
3.程式碼:
/**
* Definition of ListNode
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param node: a node in the list should be deleted
* @return: nothing
*/
void deleteNode(ListNode *node) {
// write your code here
*node=*(node->next);
}
};
4.總結
下面兩種情況分別對應了兩種錯誤。把紅字部分替換為下面的綠字部分。
(1)
node->val=node->next->val;
node=node->next;
乍一看似乎沒有什麼區別,所存資料val給了,指標也給了,但事實上這段程式碼執行是wrong answer
因為從根本上看,只是把node的下一個節點所存資料賦值給了node節點,同時讓node指標指向下一個節點,
故此沒有達到刪除node節點的目的。
(2)
node=node->next;
node->val=node->next->val;
這兩句和上面兩句看起來也有些相似,只是變了變位置,但如果執行出來結果就不是wrong answer
而是run time error了。
因此我們發現要刪除某個節點最重要的還是找到他所在的地址,*node才是真正對現在node所在的空間
進行操作。