题目:
在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方法里才能成功(待修改!!!)