删除指定链表节点237
输入是一个node,如果按照正常做法就是遍历链表,然后如果此时节点的next为要删除的节点,则cur.next=cur.next.next。但这样的复杂度是O(n)。
其实不得到节点的前一个节点也可以删除节点,把后一个节点(此时可以直接得到后一个节点,因为此时要删除的节点是已经知道的)的内容复制到前一个节点,然后删除后一个节点也可以实现,这样只需得到后一个节点就可以实现删除。如果要删除的节点在尾部,没有下一个节点,那只能顺序遍历找到删除。如果链表中只有一个节点,则删除之后还要设置头结点为空。
所以复杂度为(O(n)+(n-1)O(1))/n,结果仍为O(1)。
但是这个一定要注意是已经确定节点在链表中,没有花O(n)的时间去确认链表中一定包含这个元素。
class Solution {
public void deleteNode(ListNode node) {
if(node==null)return;
ListNode next=node.next;
node.val=next.val;
node.next=next.next;
}
}
删除链表重复节点,留下一个83
用同向双指针。
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head==null ||head.next==null)return head;
ListNode root=new ListNode(-1);
root.next=head;
ListNode fast=head.next;
ListNode slow=head;
while(fast!=null){
if(fast.val==slow.val){
fast=fast.next;
slow.next=fast;
}else{
fast=fast.next;
slow=slow.next;
}
}
return root.next;
}
}
删除链表重复节点,重复节点不留下82
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head==null || head.next==null){//如果这是只有一个节点或者没有节点,那也不存在重复节点了
return head;
}
ListNode root=new ListNode(-1);
root.next=head;
ListNode res=root;//用来表示确定没有重复的节点;
ListNode cur=head;//表示当前节点
while(cur!=null && cur.next!=null){
if(cur.val==cur.next.val){
while(cur.next!=null && cur.val==cur.next.val){
cur=cur.next;
}
res.next=cur.next;
cur=cur.next;
}else{
res=cur;
cur=cur.next;
}
}
return root.next;
}
}