面试题18:删除链表的节点
题目一:在 O(1) 时间内删除链表节点
给定单向链表的头指针和一个节点指针,定义一个函数在 O(1) 的时间内删除该节点。
常规思路
从头开始遍历链表,找到待删除节点 m 的上一个节点 p ,让 p 的 next 指针指向 m 的下一个节点,那么 m 就从链表中被删除了。显然,这样做的时间复杂度是 O(n)。
不常规思路
我们很难得到待删除节点 m 的上一个节点, 但是很容易得到待删除节点的下一个节点 q。我们将 q 的内容复制给 m,然后删除 q 即可。如果 q 为空,则直接让 m 为空即可。
这种方法基于一种假设,那就是要删除的节点一定在链表中!!(我们把这种约束推给了调用者 )
package Question18;
public class T01 {
public static void main(String[] args) {
Node head = new Node(0);
Node temp = head;
Node pToBeDeleted = null;
for(int i = 1; i < 10; i++) {
Node newNode = new Node(i);
temp.next = newNode;
temp = temp.next;
if(i == 5) {
pToBeDeleted = newNode;
}
}
solve(head, pToBeDeleted);
temp = head;
while(temp.next != null) {
System.out.println(temp.next);
temp = temp.next;
}
}
public static void solve(Node head, Node pToBeDeleted) {
if(head == null || pToBeDeleted == null) return ;
if(pToBeDeleted.next == null) pToBeDeleted=null;
pToBeDeleted.val = pToBeDeleted.next.val;
pToBeDeleted.next = pToBeDeleted.next.next;
}
}
class Node {
int val;
Node next;
public Node(int x) {
val = x;
}
@Override
public String toString() {
return "Node{" +
"val=" + val +
", next=" + next +
'}';
}
}