203. 移除链表元素
笔记
- 此处头结点并非书中头结点,所以需要构造一个伪头结点
- 不构造伪头结点的情况下,需要分成,对头结点和非头结点两种情况
C++代码
伪头结点
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead=new ListNode(0);
dummyHead->next=head;
ListNode *cur=dummyHead;
while(cur->next !=NULL){
if(cur->next->val==val){
ListNode *tmp=cur->next;
cur->next=cur->next->next;
delete tmp;
}else{
cur=cur->next;
}
}
head=dummyHead->next;
delete dummyHead;
return head;
}
};
直接求
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//头结点while!
while(head!=NULL && head->val == val){
ListNode *tmp=head;
head=head->next;
delete tmp;
}
//非头结点,不能p=head->next,因为LeetCode不支持节点初始化为空
ListNode* p=head;
while(p!=NULL && p->next!=NULL){//先写p
if(p->next->val==val){
ListNode* tmp=p->next;
p->next=p->next->next;
delete tmp;
}else{
p=p->next;
}
}
return head;
}
};
707.设计链表
笔记
- struct
- 对链表操作时:首先考虑是否有虚拟头结点,其次是否需要改变链表长度
- index<0时,插入到index=0,即在虚拟头结点后插入
- delete命令指示释放了tmp指针原本所指的那部分内存,被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后,如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针。如果之后的程序不小心使用了tmp,会指向难以预想的内存空间。
C++代码
class MyLinkedList {
public:
struct LinkedNode{
int val;
LinkedNode* next;
LinkedNode(int val):val(val),next(nullptr){}//构造函数的初始化
};
MyLinkedList() {
_dummyHead=new LinkedNode(0);
_size=0;
}
int get(int index) {
if(index>(_size-1) || index<0){
return -1;
}
LinkedNode* cur=_dummyHead->next;
while(index--){
cur=cur->next;
}
return cur->val;
}
void addAtHead(int val) {
LinkedNode *newNode=new LinkedNode(val);//new构造节点
newNode->next=_dummyHead->next;
_dummyHead->next=newNode;
_size++;//改变链表长度
}
void addAtTail(int val) {
LinkedNode* newNode=new LinkedNode(val);
LinkedNode* cur=_dummyHead;
while(cur->next != nullptr){
cur=cur->next;
}
cur->next=newNode;
_size++;
}
void addAtIndex(int index, int val) {
if(index>_size)return;
if(index<0)index=0;//如果index<0在头部插入
LinkedNode* newNode=new LinkedNode(val);
LinkedNode* cur=_dummyHead;
while(index--){
cur=cur->next;
}
newNode->next=cur->next;
cur->next=newNode;
_size++;
}
void deleteAtIndex(int index) {
if(index<0 || index>=_size)return;
LinkedNode * cur;
cur=_dummyHead;
while(index--){
cur=cur->next;
}
LinkedNode* tmp=cur->next;
cur->next=cur->next->next;
delete tmp;
tmp=nullptr;
_size--;
}
private:
int _size;
LinkedNode* _dummyHead;
};
206. 反转链表
笔记
- 没想到还能用双指针,但其实头插法已经很简单了
C++代码
头插法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL)return head;
ListNode* dummyHead=new ListNode();
ListNode* p=head;
dummyHead->next=NULL;
while(p!=NULL){
ListNode* q=p;
p=p->next;
q->next=dummyHead->next;
dummyHead->next=q;
}
head=dummyHead->next;
delete dummyHead;
dummyHead=nullptr;
return head;
}
};
双指针
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* q=head;
ListNode* p=NULL;
while(q!=NULL){
ListNode* qq=q->next;
q->next=p;
p=q;
q=qq;
}
head=p;
return head;
}
};