剑指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 上进行下载。

猜你喜欢

转载自blog.csdn.net/FireFox1997/article/details/81451145