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