剑指offer O(1) 删除链表的节点(案例全通过)~~~~

题目:

在O(1)时间内删除链表节点。

思路:一般删除的做法是要找到删除该节点的前一个点,所以要遍历一遍,复杂度为O(n),但并不是一定要得到前一个点,可以把删除的后一个点j复制到该节点i,然后i指向j的下一个节点。

需要考虑两点:当删除位于链尾,此时就得遍历,总的平均时间复杂度就是[(n-1)*1+O(n)]/n,结果还是O(1)。;如果链表只有一个节点,删除后设为null。

(传参看完再修改,代码可以通过,改下返回值就行了)

public class Solution{
    static class Node {
        int val;
        Node next = null;
        Node(int val) {
            this.val = val;
        }
    }

    private static Node insert(int[] array){
        if(array == null) return null;

        Node head = new Node(array[0]);
        Node cur = head;
        for(int i = 1; i < array.length; i ++){
            Node node = new Node(array[i]);
            cur.next = node;
            cur = node;
        }
        return head;
    }

    private static void show(Node head){
        if(head == null){
            System.out.println("该链表为空");
            return;
        }

        Node cur = head;
        while(cur.next != null){
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
        System.out.print(cur.val);
    }

    public static Node deleteNode(Node head, Node node){
        if(head == null)return null;

        //删除尾结点(不止一个节点)
        if(head != node && node.next == null){
            while(head.next != node){
                head = head.next;
            }
            head.next = null;
        }
        //删除头结点(只有一个节点)
        else if(head == node && head.next == null){
           /*
           如果是这样的话,返回值为空,传参为空,即就能显示出来了
           head = null;
            return null;*/

        }
        //删除头结点(后还有结点)
        else if(head == node && head.next != null){
             // head.next = head; 走入死循环了,指向自己了
             // head = head.next;
             // head走下一个,尽管是可以,但是要返回类型,不算真正的删除
              head.val = head.next.val;
              head.next = head.next.next;

        }
        //中间普通节点
        else{
            node.val = node.next.val;
            node.next = node.next.next;
            //指向null无所谓
        }
        return null;
    }

    public static void main(String[] args) {
        int[] arr = new int[]{2,1,3,4};
        Node head = insert(arr);

        show(head);
        deleteNode(head, head);
        System.out.println();
        System.out.println("----(删除头结点)删除后---");
        show(head);

        System.out.println();
        System.out.println("----新的例子----");
        int[] arr1 = new int[]{2};
        Node head1 = insert(arr1);

        show(head1);
        deleteNode(head1, head1);
        System.out.println();
        System.out.println("----(删除只有一个头结点)删除后---");
        show(head1);
    }
}

注意点:

在删除时考虑头节点和尾结点,4中情况很明确

  • 删除时应该返回头节点,这样比较好理解
  • 在传参的时候一直理解出错,导致空指针异常,找个时间补一下这一块知识点
  • 只有一个节点的删除,要把返回值修为return,也要把delete写入show方法里才能成功(待修改!!!)


猜你喜欢

转载自blog.csdn.net/jae_wang/article/details/80322649