劍指offer之刪除鏈表節點


title: 刪除鏈表節點
date: 2018-08-06 08:28:59
tags: 劍指offer

1. 題目

在 O(1) 時間內刪除鏈表節點。

給定單向鏈表節點的頭指針和一個節點指針(使用 java 實現,因此我的代碼中頭結點作爲一個變量定義在類中),定義一個函數在 O(1) 時間內刪除該節點。

2. 思路

在單向鏈表中刪除節點按照常規的思路來說就是從頭開始遍歷,查找到需要刪除的節點,並在鏈表中刪除該節點。但是這種做法的時間複雜度爲 O(N),並不符合題目要求,因此需要考慮一下其他的思路。

首先,看一下鏈表內部使用的數據結構:

private class Node{
    private Object value;
    private Node next;

    public Node(Object value,Node next){
        this.value = value;
        this.next = next;
    }
}

一個節點包含這個節點的值以及下一個節點的引用。如果要刪除這個節點的值,可以通過將下一個節點的內容複製到要刪除的這個節點,通過這樣的動作也是可以刪除節點的。例如,有這樣的一個鏈表:

1 -> 2 -> 3 -> 4 -> 5

如果要刪除 3 這個節點,那麼,我們可以將 4 這個節點的值覆蓋 3 這個節點的值,用 4 這個節點的 next 變量覆蓋 3 這個節點的 next 變量,這個過程下來,鏈表中就將 3 這個節點刪除了。

但是這個過程需要注意,如果這個節點是最後一個節點,就沒辦法通過上述的方法來完成,只能通過常規的方法來解決了。

還有一個情況需要注意,如果這個節點是頭結點並且整個鏈表中只有一個節點,這時候我們就需要將鏈表的頭結點置爲空。代碼的實現如下:

private Node head;
private Node tail;

public void deleteNode(Node toBeDelete){
    if(head==null || toBeDelete==null)
        return;
    if(toBeDelete.next!=null){
        Node nextNode = toBeDelete.next;
        toBeDelete.value = nextNode.value;
        toBeDelete.next = nextNode.next;
    }else if(head.value.equals(toBeDelete.value)){
        head = null;
        tail = null;
    }else{
        Node currentNode = head;
        while(!toBeDelete.value.equals(currentNode.next.value)){
            currentNode = currentNode.next;
        }
        currentNode.next = null;
    }
}

// 打印鏈表的方法
public void printLinkList(){
    Node currentNode = head;
    while(currentNode!=null){
        System.out.println(currentNode.value);
        currentNode = currentNode.next;
    }
}

// 鏈表添加元素的方法
public void add(Object value){
    Node temp = new Node(value,null);
    if(head==null){
        head = temp;
        tail = temp;
    }else{
        tail.next = temp;
        tail = tail.next;
    }
}

3. 注意點

這個方法的時間複雜度是不是 O(1) 呢?答案是肯定的,其時間複雜度爲 [ (n-1)*O(1) + O(n) ] / n = O(1)。

這個思路是基於一個假設上實現的,就是要刪除的元素需要在鏈表內,爲了符合時間複雜度爲 O(1) 的要求,就沒辦法在函數中進行判斷,因此需要由調用該函數的人來保證。這在面試過程中可以和面試官進行探討,可以讓面試官對我們有一個更好的印象。

詳細的代碼可以上 github 上進行下載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章