本题最大的要求是 在时间复杂度为o(1) 的要求内删除 给出的节点
如按照 通常算法 依次遍历,找到 给定节点的前节点,时间复杂度为o(n) ,不符合要求
所以肯定不能遍历链表
思路:假设该节点p肯定在链表内,那么只用找到 该节点的后续节点q,将其赋值给当前结点,然后将p
指向q的下一个节点 ,最后删除q即可
但是,如果p在链表尾部,只能依次遍历了
代码如下
/**
*
*/
/***
* @author 18071
* @Date 2019年2月28日
* 功能: 一时间复杂度为 O(1) 删除来目标中给定的链表的节点!
***/
public class test {
public static void main(String args[]) {
listcode head=new listcode(0);
listcode head1=head;
listcode head11=head;
listcode l1=new listcode(1);
listcode l2=new listcode(2);
listcode l3=new listcode(3);
listcode l4=new listcode(4);
listcode l5=new listcode(5);
head.next=l1;
l1.next=l2;
l2.next=l3;
l3.next=l4;
l4.next=l5;
System.out.println("delete 之前 ");
while(head!=null) {
System.out.println(head.value);
head=head.next;
}
delete delete=new delete();
delete.de(head, l3);
System.out.println("delete 后 ");
while(head1!=null) {
System.out.println(head1.value);
head1=head1.next;
}
System.out.println("delete 尾节点 后 ");
delete.de(head11, l5);
while(head11!=null) {
System.out.println(head11.value);
head11=head11.next;
}
}
}
class delete{
public void de(listcode head,listcode p) {
if(p.next!=null) {
listcode temp=p.next;
p.value=temp.value;
p.next=temp.next;
}
else {
while(head!=null&&head.next!=p) {
head=head.next;
}
//此时head 为p的前一个节点
head.next=head.next.next;
}
}
}
class listcode {
int value;
listcode next;
listcode(int x){
this.value=x;
}
}
题目变种
代码如下,主要时采用 快慢指针的思想
只要快指针和它后面的节点值相同,fast就一直往后 ,停止后 ,连接 slow 与fast 这样就将 中间重复的 节点删除了
《特别注意 ,此时 我没有考虑 开头就有 重复的可能 ,可以在开头加入 一个比较 如果slow 和fast相同 ,fast 一直向后,直到 fast.value !=fast.next.value , 最后 重新赋值 slow 和 fast 即可 确保开头不是重复的 》
class delete {
public void d(listcode head) {
// test 前后指针 ,当 前后两指针不相同时,都往后移动 ,当遇到 前后指针相同时,快指针继续往前走 ,走到 不同时,慢指针 后退,连接快慢指针 即可
listcode slow = head;
listcode fast = head.next;
while (fast.next!= null&&fast!=null) {
System.out.println(" now fast. value =="+fast.value);
while (fast.value != fast.next.value) {
slow=slow.next;
fast=fast.next;
}
fast=fast.next.next;
slow.next=fast;
}
}
}