题目一:在o(1)的时间内删除指定的节点
常规的做法就是从链表的头结点开始,顺序遍历查找要删除的节点。因为要找到一个删除节点的前节点,时间复杂度为o(n)。这并不符合题目要求。
方法:可以把下一个节点的内容复制到需要删除的节点上覆盖原有内容,再把下一个节点删除
注意:
(1)如果要删除的节点位于链表的尾部,那么就没有下一个节点了,仍然从链表的头结点开始,顺序遍历得到该节点的前序节点,并完成删除操作
(2)如果链表中只有一个节点,又要删除这个链表的节点,删除节点之后,需要把链表的头结点设置为null
(3)默认的是这个链表中肯定包含这个删除的节点,因为这个查找这个站点需要o(n)的时间
这个方法需要注意的是代码的完整性,需要考虑到这个删除的节点处于的位置。
public ListNode deleteNode(ListNode pHead,ListNode deleteNode){
if(pHead==null || deleteNode==null)
{
return null;
}
//删除的节点不是尾节点
if(deleteNode.next!=null){
ListNode deleteNext=deleteNode.next;
deleteNode.val=deleteNext.val;
deleteNext.next=deleteNext.next;
deleteNext=null;
}
//链表中只有一个节点,这个节点是需要删除的
else if(pHead==deleteNode){
pHead=null;
deleteNode=null;
}
//删除的节点位于尾结点
else{
ListNode p=pHead;
while(p.next!=deleteNode){
p=p.next;
}
p.next=null;
}
return pHead;
}
题目二:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。
方法:遍历整个链表,如果当前节点的值与下一个节点相同,就是重复节点,就可以进行删除。 * 把当前节点的前一个节点和后面值比当前节点值大的节点连接起来。
public ListNode deleteDuplication(ListNode pHead)
{
//只有一个节点就返回
if(pHead==null || pHead.next==null){
return pHead;
}
//创建头结点,这样的话,第一个节点重复也好处理,如果没有头结点,第一个节点重复,就很麻烦
ListNode head=new ListNode(0);
head.next=pHead;
ListNode pre=head;
ListNode last=head.next;
while (last!=null)
{
if(last.next != null && last.val == last.next.val) {
while (last.next != null && last.val == last.next.val) {
last = last.next;
}
pre.next = last.next;
last = last.next;
}
else
{
pre=pre.next;
last=last.next;
}
}
return head.next;
}
注意:这个需要添加一个头结点,因为第一个结点也有可能重复,添加一个头结点后,方便操作