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

来源:互联网 发布:ps mac版多少钱 编辑:程序博客网 时间:2024/05/29 04:26

题目描述

给定单向链表的头指针和一个结点指针,定义一个函数在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)判断
0 0
原创粉丝点击