链表的增删操作时间复杂度O(1),查询时间复杂度O(n),因为要从头结点开始。使用场景和数据完全相反
链表的储存地址是不连续的。也和数组不同。
利用虚拟头结点可以同意操作。不然删除头结点需要额外写。
记得返回的是虚拟头结点的next而不是虚拟头结点return dummyhead。哈哈哈
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyhead = new ListNode(60);
dummyhead->next=head;
ListNode* cur=dummyhead;
while(cur->next!=NULL){
if(cur->next->val == val){
ListNode* temp=cur->next;
cur->next = cur->next->next;
delete temp;
}
else{
cur=cur->next;
}
}
return dummyhead->next;
}
};
总是忘记判定插入或者删除的位置是否有效。
class MyLinkedList {
public:
struct ListNode {
int val;
ListNode *next;
ListNode(int val) : val(val), next(nullptr) {}
};
MyLinkedList() {
dummyhead=new ListNode(0);
size=0;
}
int get(int index) {
if(index>size-1)
return -1;
ListNode* cur=dummyhead->next;
for(int i=0;i<index;i++){
cur=cur->next;
}
return cur->val;
}
void addAtHead(int val) {
ListNode* head= new ListNode(val);
head->next=dummyhead->next;
dummyhead->next=head;
size++;
}
void addAtTail(int val) {
if(size==0) dummyhead->next=new ListNode(val);
else{
ListNode* cur=dummyhead->next;
while(cur->next != NULL){
cur=cur->next;
}
cur->next= new ListNode(val);
}
size++;
}
void addAtIndex(int index, int val) {
if(index>size) return;
ListNode* cur=dummyhead;
for(int i=0;i<index;i++){
cur=cur->next;
}
ListNode* temp=new ListNode(val);
temp->next=cur->next;
cur->next=temp;
size++;
}
void deleteAtIndex(int index) {
if(index>=size) return;
ListNode* cur=dummyhead;
for(int i=0;i<index;i++){
cur=cur->next;
};
ListNode* temp=cur->next;
cur->next=cur->next->next;
delete temp;
size--;
}
//void printLinkedList(){
//}
private:
int size;
ListNode* dummyhead;
};
中间过程想到了用三个指针,双指针+储存临时下一个的指针。
但是开头和结尾的处理过程没想出来。
直接让pre=head,这样的话还得加上head->next=nullptr才表示一条链表结束了。
所以让pre=null就不用特殊处理开头和结尾了。
ListNode* reverseList(ListNode* head) {
//if(head->next==nullptr) return nullptr;
//ListNode* dummyhead= new ListNode(0);
//dummyhead->next=head;
//ListNode* pre=head;
//ListNode* cur=pre->next;
//ListNode* next=cur->next;
//cur->next=pre;
//head=reversal(cur,next);
//return head;
if(head==nullptr) return nullptr;
ListNode* pre=nullptr;
ListNode* cur=head;
while(cur!=nullptr){
ListNode* next=cur->next;
cur->next=pre;
pre=cur;
cur=next;
}
return pre;
}
快忘记递归怎么写啦,就是递归套递归。
class Solution {
private:
ListNode* reversal(ListNode* pre,ListNode* cur){
if(cur==nullptr) return pre;
ListNode* temp=cur->next;
cur->next=pre;
return reversal(cur,temp);
}
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre=nullptr;
ListNode* cur=head;
return reversal(pre,cur);
}
};