get(index):遍历链表,找到第 index 个节点,返回其值,如果不存在,返回 $-1$。时间复杂度 $O(n)$。
addAtHead(val):创建新节点,将其插入到虚拟头节点后面。时间复杂度 $O(1)$。
addAtTail(val):创建新节点,将其插入到链表尾部。时间复杂度 $O(n)$。
addAtIndex(index, val):如果 index 等于链表长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果 index 小于 $0$,则在头部插入节点。否则,遍历链表,找到第 index 个节点的前一个节点,将新节点插入到该节点后面。时间复杂度 $O(n)$。
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。否则,不做任何操作。时间复杂度 $O(n)$。
classMyLinkedList:def__init__(self):self.dummy=ListNode()self.cnt=0defget(self,index:int)->int:ifindex<0orindex>=self.cnt:return-1cur=self.dummy.nextfor_inrange(index):cur=cur.nextreturncur.valdefaddAtHead(self,val:int)->None:self.addAtIndex(0,val)defaddAtTail(self,val:int)->None:self.addAtIndex(self.cnt,val)defaddAtIndex(self,index:int,val:int)->None:ifindex>self.cnt:returnpre=self.dummyfor_inrange(index):pre=pre.nextpre.next=ListNode(val,pre.next)self.cnt+=1defdeleteAtIndex(self,index:int)->None:ifindex>=self.cnt:returnpre=self.dummyfor_inrange(index):pre=pre.nextt=pre.nextpre.next=t.nextt.next=Noneself.cnt-=1# Your MyLinkedList object will be instantiated and called as such:# obj = MyLinkedList()# param_1 = obj.get(index)# obj.addAtHead(val)# obj.addAtTail(val)# obj.addAtIndex(index,val)# obj.deleteAtIndex(index)
classMyLinkedList{privateListNodedummy=newListNode();privateintcnt;publicMyLinkedList(){}publicintget(intindex){if(index<0||index>=cnt){return-1;}varcur=dummy.next;while(index-->0){cur=cur.next;}returncur.val;}publicvoidaddAtHead(intval){addAtIndex(0,val);}publicvoidaddAtTail(intval){addAtIndex(cnt,val);}publicvoidaddAtIndex(intindex,intval){if(index>cnt){return;}varpre=dummy;while(index-->0){pre=pre.next;}pre.next=newListNode(val,pre.next);++cnt;}publicvoiddeleteAtIndex(intindex){if(index<0||index>=cnt){return;}varpre=dummy;while(index-->0){pre=pre.next;}vart=pre.next;pre.next=t.next;t.next=null;--cnt;}}/** * Your MyLinkedList object will be instantiated and called as such: * MyLinkedList obj = new MyLinkedList(); * int param_1 = obj.get(index); * obj.addAtHead(val); * obj.addAtTail(val); * obj.addAtIndex(index,val); * obj.deleteAtIndex(index); */
classMyLinkedList{private:ListNode*dummy=newListNode();intcnt=0;public:MyLinkedList(){}intget(intindex){if(index<0||index>=cnt){return-1;}autocur=dummy->next;while(index--){cur=cur->next;}returncur->val;}voidaddAtHead(intval){addAtIndex(0,val);}voidaddAtTail(intval){addAtIndex(cnt,val);}voidaddAtIndex(intindex,intval){if(index>cnt){return;}autopre=dummy;while(index-->0){pre=pre->next;}pre->next=newListNode(val,pre->next);++cnt;}voiddeleteAtIndex(intindex){if(index>=cnt){return;}autopre=dummy;while(index-->0){pre=pre->next;}autot=pre->next;pre->next=t->next;t->next=nullptr;--cnt;}};/** * Your MyLinkedList object will be instantiated and called as such: * MyLinkedList* obj = new MyLinkedList(); * int param_1 = obj->get(index); * obj->addAtHead(val); * obj->addAtTail(val); * obj->addAtIndex(index,val); * obj->deleteAtIndex(index); */
typeMyLinkedListstruct{dummy*ListNodecntint}funcConstructor()MyLinkedList{returnMyLinkedList{&ListNode{},0}}func(this*MyLinkedList)Get(indexint)int{ifindex<0||index>=this.cnt{return-1}cur:=this.dummy.Nextfor;index>0;index--{cur=cur.Next}returncur.Val}func(this*MyLinkedList)AddAtHead(valint){this.AddAtIndex(0,val)}func(this*MyLinkedList)AddAtTail(valint){this.AddAtIndex(this.cnt,val)}func(this*MyLinkedList)AddAtIndex(indexint,valint){ifindex>this.cnt{return}pre:=this.dummyfor;index>0;index--{pre=pre.Next}pre.Next=&ListNode{val,pre.Next}this.cnt++}func(this*MyLinkedList)DeleteAtIndex(indexint){ifindex<0||index>=this.cnt{return}pre:=this.dummyfor;index>0;index--{pre=pre.Next}t:=pre.Nextpre.Next=t.Nextt.Next=nilthis.cnt--}/** * Your MyLinkedList object will be instantiated and called as such: * obj := Constructor(); * param_1 := obj.Get(index); * obj.AddAtHead(val); * obj.AddAtTail(val); * obj.AddAtIndex(index,val); * obj.DeleteAtIndex(index); */
classLinkNode{publicval:number;publicnext:LinkNode;constructor(val:number,next:LinkNode=null){this.val=val;this.next=next;}}classMyLinkedList{publichead:LinkNode;constructor(){this.head=null;}get(index:number):number{if(this.head==null){return-1;}letcur=this.head;letidxCur=0;while(idxCur<index){if(cur.next==null){return-1;}cur=cur.next;idxCur++;}returncur.val;}addAtHead(val:number):void{this.head=newLinkNode(val,this.head);}addAtTail(val:number):void{constnewNode=newLinkNode(val);if(this.head==null){this.head=newNode;return;}letcur=this.head;while(cur.next!=null){cur=cur.next;}cur.next=newNode;}addAtIndex(index:number,val:number):void{if(index<=0){returnthis.addAtHead(val);}constdummy=newLinkNode(0,this.head);letcur=dummy;letidxCur=0;while(idxCur<index){if(cur.next==null){return;}cur=cur.next;idxCur++;}cur.next=newLinkNode(val,cur.next||null);}deleteAtIndex(index:number):void{if(index==0){this.head=(this.head||{}).next;return;}constdummy=newLinkNode(0,this.head);letcur=dummy;letidxCur=0;while(idxCur<index){if(cur.next==null){return;}cur=cur.next;idxCur++;}cur.next=(cur.next||{}).next;}}/** * Your MyLinkedList object will be instantiated and called as such: * var obj = new MyLinkedList() * var param_1 = obj.get(index) * obj.addAtHead(val) * obj.addAtTail(val) * obj.addAtIndex(index,val) * obj.deleteAtIndex(index) */
#[derive(Default)]structMyLinkedList{head:Option<Box<ListNode>>,}/** * `&self` means the method takes an immutable reference. * If you need a mutable reference, change it to `&mut self` instead. */implMyLinkedList{fnnew()->Self{Default::default()}fnget(&self,mutindex:i32)->i32{ifself.head.is_none(){return-1;}letmutcur=self.head.as_ref().unwrap();whileindex>0{matchcur.next{None=>{return-1;}Some(refnext)=>{cur=next;index-=1;}}}cur.val}fnadd_at_head(&mutself,val:i32){self.head=Some(Box::new(ListNode{val,next:self.head.take(),}));}fnadd_at_tail(&mutself,val:i32){letnew_node=Some(Box::new(ListNode{val,next:None}));ifself.head.is_none(){self.head=new_node;return;}letmutcur=self.head.as_mut().unwrap();whileletSome(refmutnext)=cur.next{cur=next;}cur.next=new_node;}fnadd_at_index(&mutself,mutindex:i32,val:i32){letmutdummy=Box::new(ListNode{val:0,next:self.head.take(),});letmutcur=&mutdummy;whileindex>0{ifcur.next.is_none(){return;}cur=cur.next.as_mut().unwrap();index-=1;}cur.next=Some(Box::new(ListNode{val,next:cur.next.take(),}));self.head=dummy.next;}fndelete_at_index(&mutself,mutindex:i32){letmutdummy=Box::new(ListNode{val:0,next:self.head.take(),});letmutcur=&mutdummy;whileindex>0{ifletSome(refmutnext)=cur.next{cur=next;}index-=1;}cur.next=cur.next.take().and_then(|n|n.next);self.head=dummy.next;}}
方法二:静态数组实现单链表
在方法一中,我们使用了指针引用的方式,每次动态创建一个链表节点。在链表节点数量达到 $10^5$ 甚至更大时,频繁执行 new 操作,会大大增加程序的执行耗时。
classMyLinkedList:def__init__(self):self.e=[0]*1010self.ne=[0]*1010self.idx=0self.head=-1self.cnt=0defget(self,index:int)->int:ifindex<0orindex>=self.cnt:return-1i=self.headfor_inrange(index):i=self.ne[i]returnself.e[i]defaddAtHead(self,val:int)->None:self.e[self.idx]=valself.ne[self.idx]=self.headself.head=self.idxself.idx+=1self.cnt+=1defaddAtTail(self,val:int)->None:self.addAtIndex(self.cnt,val)defaddAtIndex(self,index:int,val:int)->None:ifindex>self.cnt:returnifindex<=0:self.addAtHead(val)returni=self.headfor_inrange(index-1):i=self.ne[i]self.e[self.idx]=valself.ne[self.idx]=self.ne[i]self.ne[i]=self.idxself.idx+=1self.cnt+=1defdeleteAtIndex(self,index:int)->None:ifindex<0orindex>=self.cnt:return-1self.cnt-=1ifindex==0:self.head=self.ne[self.head]returni=self.headfor_inrange(index-1):i=self.ne[i]self.ne[i]=self.ne[self.ne[i]]# Your MyLinkedList object will be instantiated and called as such:# obj = MyLinkedList()# param_1 = obj.get(index)# obj.addAtHead(val)# obj.addAtTail(val)# obj.addAtIndex(index,val)# obj.deleteAtIndex(index)
classMyLinkedList{privateint[]e=newint[1010];privateint[]ne=newint[1010];privateinthead=-1;privateintidx;privateintcnt;publicMyLinkedList(){}publicintget(intindex){if(index<0||index>=cnt){return-1;}inti=head;while(index-->0){i=ne[i];}returne[i];}publicvoidaddAtHead(intval){e[idx]=val;ne[idx]=head;head=idx++;++cnt;}publicvoidaddAtTail(intval){addAtIndex(cnt,val);}publicvoidaddAtIndex(intindex,intval){if(index>cnt){return;}if(index<=0){addAtHead(val);return;}inti=head;while(--index>0){i=ne[i];}e[idx]=val;ne[idx]=ne[i];ne[i]=idx++;++cnt;}publicvoiddeleteAtIndex(intindex){if(index<0||index>=cnt){return;}--cnt;if(index==0){head=ne[head];return;}inti=head;while(--index>0){i=ne[i];}ne[i]=ne[ne[i]];}}/** * Your MyLinkedList object will be instantiated and called as such: * MyLinkedList obj = new MyLinkedList(); * int param_1 = obj.get(index); * obj.addAtHead(val); * obj.addAtTail(val); * obj.addAtIndex(index,val); * obj.deleteAtIndex(index); */
classMyLinkedList{private:inte[1010],ne[1010];inthead=-1,idx=0,cnt=0;public:MyLinkedList(){}intget(intindex){if(index<0||index>=cnt){return-1;}inti=head;while(index--){i=ne[i];}returne[i];}voidaddAtHead(intval){e[idx]=val;ne[idx]=head;head=idx++;++cnt;}voidaddAtTail(intval){addAtIndex(cnt,val);}voidaddAtIndex(intindex,intval){if(index>cnt){return;}if(index<=0){addAtHead(val);return;}inti=head;while(--index){i=ne[i];}e[idx]=val;ne[idx]=ne[i];ne[i]=idx++;++cnt;}voiddeleteAtIndex(intindex){if(index<0||index>=cnt){return;}--cnt;if(index==0){head=ne[head];return;}inti=head;while(--index){i=ne[i];}ne[i]=ne[ne[i]];}};/** * Your MyLinkedList object will be instantiated and called as such: * MyLinkedList* obj = new MyLinkedList(); * int param_1 = obj->get(index); * obj->addAtHead(val); * obj->addAtTail(val); * obj->addAtIndex(index,val); * obj->deleteAtIndex(index); */
typeMyLinkedListstruct{e[]intne[]intidxintheadintcntint}funcConstructor()MyLinkedList{e:=make([]int,1010)ne:=make([]int,1010)returnMyLinkedList{e,ne,0,-1,0}}func(this*MyLinkedList)Get(indexint)int{ifindex<0||index>=this.cnt{return-1}i:=this.headfor;index>0;index--{i=this.ne[i]}returnthis.e[i]}func(this*MyLinkedList)AddAtHead(valint){this.e[this.idx]=valthis.ne[this.idx]=this.headthis.head=this.idxthis.idx++this.cnt++}func(this*MyLinkedList)AddAtTail(valint){this.AddAtIndex(this.cnt,val)}func(this*MyLinkedList)AddAtIndex(indexint,valint){ifindex>this.cnt{return}ifindex<=0{this.AddAtHead(val)return}i:=this.headfor;index>1;index--{i=this.ne[i]}this.e[this.idx]=valthis.ne[this.idx]=this.ne[i]this.ne[i]=this.idxthis.idx++this.cnt++}func(this*MyLinkedList)DeleteAtIndex(indexint){ifindex<0||index>=this.cnt{return}this.cnt--ifindex==0{this.head=this.ne[this.head]return}i:=this.headfor;index>1;index--{i=this.ne[i]}this.ne[i]=this.ne[this.ne[i]]}/** * Your MyLinkedList object will be instantiated and called as such: * obj := Constructor(); * param_1 := obj.Get(index); * obj.AddAtHead(val); * obj.AddAtTail(val); * obj.AddAtIndex(index,val); * obj.DeleteAtIndex(index); */
classMyLinkedList{e:Array<number>;ne:Array<number>;idx:number;head:number;cnt:number;constructor(){this.e=newArray(1010).fill(0);this.ne=newArray(1010).fill(0);this.head=-1;this.idx=0;this.cnt=0;}get(index:number):number{if(index<0||index>=this.cnt){return-1;}leti=this.head;while(index--){i=this.ne[i];}returnthis.e[i];}addAtHead(val:number):void{this.e[this.idx]=val;this.ne[this.idx]=this.head;this.head=this.idx++;this.cnt++;}addAtTail(val:number):void{this.addAtIndex(this.cnt,val);}addAtIndex(index:number,val:number):void{if(index>this.cnt){return;}if(index<=0){this.addAtHead(val);return;}leti=this.head;while(--index){i=this.ne[i];}this.e[this.idx]=val;this.ne[this.idx]=this.ne[i];this.ne[i]=this.idx++;this.cnt++;}deleteAtIndex(index:number):void{if(index<0||index>=this.cnt){return;}this.cnt--;if(index==0){this.head=this.ne[this.head];return;}leti=this.head;while(--index){i=this.ne[i];}this.ne[i]=this.ne[this.ne[i]];}}/** * Your MyLinkedList object will be instantiated and called as such: * var obj = new MyLinkedList() * var param_1 = obj.get(index) * obj.addAtHead(val) * obj.addAtTail(val) * obj.addAtIndex(index,val) * obj.deleteAtIndex(index) */