18: O(1)时间下删除链表的节点

O(1)删除链表中的节点

给出一个链表的节点,要求 O(1) 时间复杂度下在链表中删除该节点
要分三种情况

  1. toBeDeleted 是头节点,更改head = head.next;
  2. toBeDeleted 是尾节点,此时要遍历找到尾节点的前驱节点pre, 让pre = null
  3. 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;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_41889284/article/details/89413261