剑指offer面试题13 在O(1)时间删除链表节点

来源:互联网 发布:夏河淘宝日货是正品吗 编辑:程序博客网 时间:2024/06/10 19:03

解题思路:

1.在链表中删除某个节点的常规思路是从链表的头结点开始,顺序遍历查找要删除的节点,找到待删除节点的前一个节点,进行删除操作,但是这种思路需要顺序查找,因此时间复杂度为O(n)。现在可以这样考虑,已知待删除节点toBeDeleted,那么可以很容易地在O(1)时间内找到待删除节点的下一个节点later,将later节点中的元素赋值给toBeDeleted节点中的元素,那么此时toBeDeleted相当于是later节点的拷贝,此时再将later节点删除,那么就实现了变向地删除toBeDeleted节点。

2.但还需考虑一些特殊测试用例,(1)当链表中只有一个节点,即待删除节点就是头结点Head时,删除后链表为空;(2)如果待删除节点是链表的尾节点,那么1.中的方法不起作用,此时只能从链表的头开始遍历,直到待删除节点的前一个节点,在进行删除。

注:本题的待删除节点toBeDeleted都是默认存在于链表中的,只有这样才能保证以O(1)时间删除节点。

class ListNode {int val;ListNode next = null;public ListNode(int val) {this.val = val;}}public class Solution {/** * 在0(1)时间内删除某个节点 *  * @param head * @param toBeDeleted */public void deleteNode(ListNode head, ListNode toBeDeleted) {if (head == null || toBeDeleted == null) {return;}// 如果链表中只有一个节点,即头结点就是待删除节点if (head.next == null && head == toBeDeleted) {head = null;return;}// 如果待删除节点是链表的尾节点,还是得顺序遍历到链表尾节点的前一个节点// 这种情况的时间复杂度为Onif (toBeDeleted.next == null) {// 定位到末节点的前一个节点ListNode p = head;while (p.next != toBeDeleted) {p = p.next;}// 进行删除节点操作p.next = toBeDeleted.next;return;}// 一般情况,待删除的节点不是尾节点想在O(1)时间删除链表上的某个节点,将待删除节点的下一个节点的内容复制到// 到待删除节点上,然后删除待删除节点的下一个节点,即变向地完成了删除待删除节点的操作// 获取待删除节点的下一个节点ListNode later = toBeDeleted.next;toBeDeleted.val = later.val;toBeDeleted.next = later.next;}}


阅读全文
0 0