O(1)删除链表中的节点
给出一个链表的节点,要求 O(1) 时间复杂度下在链表中删除该节点
要分三种情况
- toBeDeleted 是头节点,更改head = head.next;
- toBeDeleted 是尾节点,此时要遍历找到尾节点的前驱节点pre, 让pre = null
- toBeDelted 是中间节点,复制 pre 到toBeDeleted, 越过pre指向pre.next
这样只有要删除的节点是尾节点时,需要遍历链表,时间复杂度是O(n),但是经过分摊后,时间复杂度是O(1)
要注意的是,这种删除链表的方法需要提前确保该节点在链表内,否则会出现错误.
public static Node delete(Node head, Node toBeDeleted) {
if (head == null || toBeDeleted == null) {
return head;
}
if (head == toBeDeleted) {
head = toBeDeleted.next;
} else if (toBeDeleted.next == null) {
Node pre = head;
while (pre.next != toBeDeleted) {
pre = pre.next;
}
pre.next = null;
} else {
Node next = toBeDeleted.next;
toBeDeleted.val = next.val;
toBeDeleted.next = next.next;
}
return head;
}
删除链表中重复的节点
删除链表中重复的节点 (全删除)
递归方式,递归终止条件是,当前节点是尾节点或 null
当head是重复项时,定位下一个不和head重复的节点
当head不是重复项时,处理head.next
public static Node deleteDuplication(Node head) {
if (head == null || head.next == null) {
return head;
}
Node next = head.next;
if (head.val == next.val) { //head节点重复
while (next.next != null && next.next.val == head.val) {
next = next.next;
}
//定位到下一个要判断的节点
return deleteDuplication(next.next);
} else { //当前节点不重复
head.next = deleteDuplication(next);
return head;
}
}