剑指offer java NO14

NO14: 给定单向链表的头指针和一个结点指针, 定义一个函数在O(1)时间删除该节点

思考:在单向链表中删除一个节点,有两种方法。
a. 从头结点开始遍历,直到temp.getNext()等于要删除的节点,找到要删除的节点进行删除。时间复杂度为O(n)
b. 已知要删除的节点,这个节点的下一个节点的值覆盖掉此节点,然后此节点指向下下一个节点。时间复杂度为O(1)
在b方法中有几个点需要进行讨论:
1. 要保证时间复杂度为O(1), 那么就不允许对链表进行遍历,所以判断要删除节点的任务必须由方法调用者来做。
2. 如果要删除的节点是尾节点,b方法就不能使用了。这时候要使用a方法代替。
3. 考虑链表为空、链表只有一个节点、要删除的节点是空节点等特殊情况

先写一个单向链表的类

/**
 * @author
 * 单向链表
 */
public class Node {

    String data;
    Node next;

    public Node(String data) {
        super();
        this.data = data;
    }

    public Node(String data, Node next) {
        super();
        this.data = data;
        this.next = next;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getData() {
        return data;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    public Node getNext() {
        return next;
    }
}

解题代码:

import com.company.base.Node;

/**
 * 给定单向链表的头指针和一个结点指针, 定义一个函数在O(1)时间删除该节点
 */
public class NO14 {
    public static void main(String[] args) {
        Node node1 = new Node("1");
        Node node2 = new Node("2");
        Node node3 = new Node("3");
        Node node4 = new Node("4");
        Node node5 = new Node("5");
        Node node6 = new Node("6");
        node1.setNext(node2);
        node2.setNext(node3);
        node3.setNext(node4);
        node4.setNext(node5);
        node5.setNext(node6);
        NO14A no14A = new NO14A();
        no14A.printList(node1);
        System.out.println();
        no14A.deleteNodeAndPrintList(node1, node3);
    }
}

class NO14A{

    public void deleteNodeAndPrintList(Node head, Node toBeDeleted){
        printList(deleteNode(head, toBeDeleted));
    }

    //要删除的节点必须在链表中存在,这由调用者保证
    //删除某个节点
    public Node deleteNode(Node head, Node toBeDeleted){
        //链表为空或者删除的节点是空节点
        if (head == null || toBeDeleted == null){
            return head;
        }
        //链表只有一个节点,且要删除头结点
        if (head.getNext() == null){
            head.setData(null);
        }
        //链表有多个节点,删除的是头结点
        if (head == toBeDeleted){
            head = head.getNext();
        }
        //链表有多个节点,删除的是尾节点
        if (toBeDeleted.getNext() == null){
            Node temp = head;
            while (temp.getNext() != toBeDeleted){
                temp = temp.getNext();
            }
            temp.setNext(null);
        }
        //链表有多个节点,删除的是普通节点
        else{
            toBeDeleted.setData(toBeDeleted.getNext().getData());
            toBeDeleted.setNext(toBeDeleted.getNext().getNext());
        }
        return head;
    }

    //打印链表
    public void printList(Node head){
        Node temp = head;
        while (temp.getNext() != null){
            System.out.println(temp.getData());
            temp = temp.getNext();
        }
    }
}

运行结果:

1
2
3
4
5

1
2
4
5

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/TaylorSwift_1989/article/details/89330360