1. 程式人生 > >Lintcode 在O(1)時間複雜度刪除連結串列節點

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所在的空間

進行操作。