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

题目描述

给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点

初始条件

class ListNode{
        int val;
        ListNode next;
        ListNode(int val){
            this.val=val;
        }

}

思路:单向链表,删除结点,先找到该结点,从头遍历到待删除结点,时间O(n)。删除时保证链表不断。

public static void DelNodeInListO_n(ListNode pListNode,ListNode pToBeDeleted){
        if(pListNode==null||pToBeDeleted==null)
            return;
        //case1:deleted node is head node
        //case2:deleted node is not head node

        //case1
        if(pListNode==pToBeDeleted){
            pListNode=null;
            pToBeDeleted=null;
        }//end case1
        //case2
        else{
            ListNode pNode=pListNode;
            while(pNode.next!=pToBeDeleted){
                pNode=pNode.next;
            }
            pNode.next=pToBeDeleted.next;
            //delete pToBeDeleted;
            pToBeDeleted=null;
        }
    }

如何实现O(1)的算法?
删除一个结点,总是要找到它的前一个结点p,使p.next=p.next.next。由单向链表没有指向前面结点的指针,所以只能从头遍历。找到后继结点q只需O(1),我们可以将q的值赋值给p,然后删除q,就相当于删除了原来的结点p。

/**
 * 
 */
package com.su.biancheng;

import java.util.ArrayList;
import java.util.List;

/**
 * @title DeleteNodeInList.java
 * @author Shuai
 * @date 2016-4-10下午3:38:38
 */

public class DeleteNodeInList {
    public static class ListNode{
        int val;
        ListNode next;
        ListNode(int val){
            this.val=val;
        }

    }
    public static void DelNodeInList(ListNode pListNode,ListNode pToBeDeleted){
        if(pListNode==null||pToBeDeleted==null)
            return;
        //case1:deleted node is not tail node
        //case2:list has only one node,delete head node(tail node)
        //case3:list has more than one node,delete tail node

        //case1
        //new nextNode of deleted node
        //copy the content of the nextNode to cover toBeDeletednode
        //delete nextNode is equal to delete toBeDeletednode
        if(pListNode.next!=null){
            ListNode nextNode=pToBeDeleted.next;
            pToBeDeleted.val=nextNode.val;
            pToBeDeleted.next=nextNode.next;
            //delete nextNode;
            nextNode=null;

        }
        //case2
        else if(pListNode==pToBeDeleted){
            //delete pToBeDeleted;
            pToBeDeleted=null;
            pListNode=null;
        }
        //case3
        //tail node has no nextNode,only traverse list
        else{
            ListNode pNode=pListNode;
            while(pNode.next!=pToBeDeleted){
                pNode=pNode.next;
            }
            pNode.next=null;
            //delete pToBeDeleted;
            pToBeDeleted=null;
        }
    }
    public static void PrintList(ListNode pListNode){
        while(pListNode!=null){
            System.out.print(pListNode.val+"-->");
            pListNode=pListNode.next;
        }
        System.out.println("null");
    }
    public static void main(String[] args){
        List<ListNode> list=new ArrayList<ListNode>();
        list.add(new ListNode(1));
        list.add(new ListNode(2));
        list.add(new ListNode(3));
        list.add(new ListNode(4));
        list.add(new ListNode(5));
        for(int i=0;i<list.size();i++){
            ListNode listNode=list.get(i);
            if(i+1<list.size()){
                listNode.next=list.get(i+1);
            }
        }
        ListNode pListNode=list.get(0);
        ListNode pToBeDeleted=list.get(3);
        System.out.println("before delete");
        PrintList(pListNode);
        DelNodeInList(pListNode,pToBeDeleted);
        System.out.println("after deleted ");
        PrintList(pListNode);
    }
}
Note
几种特殊情况:
case1:没有下一个结点,即删除结点是尾结点
case2:如果链表只有一个结点(既是尾结点,又是头结点),需要把头结点置为空
case3:其他情况,只需把结点值复制,然后保持链表不断,使被删结点为空
Note:
时间复杂度:
[(n-1)*O(1)+O(n)]/n=O(1)

如果待删除结点不在链表中,需要O(n)判断
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值