203.移除链表元素
题目:力扣题目链接
视频:代码随想录视频讲解
在写代码时出现的问题:
ListNode* p,q;这么写是错误的,这样只能定义p.
可以分开定义。
方法一:直接删除元素
需要单独讨论一下当需要删除的元素位于头结点时的情况。
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
while(head!=nullptr&&head->val==val)//while容易写成if,例如1,1,1,1,1,1 val=1
{
head=head->next;
}
ListNode* p=head,*q;
while(head!=nullptr&&p->next!=nullptr&&p!=nullptr)
{
if(p->next->val==val)
{
q=p->next;
p->next=q->next;
delete q;
}
else//注意这里,当删除p后面的数时,还要检查一下if语句中的P的新的next符不符合
p=p->next;
}
return head;
}
};
方法二:设置一个哨兵结点,也叫虚拟头结点
在头结点前设置虚拟头结点,可以避免多讨论头结点删除的情况。
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* currenthead=new ListNode();
ListNode* p;
ListNode* q=currenthead;//q是用来遍历的,p是辅助删除的
currenthead->next=head;
while(q->next!=nullptr)
{
if(q->next->val==val)
{
p=q->next;
q->next=p->next;
delete p;
}
else
q=q->next;
}
return currenthead->next;
}
};
707.设计链表
题目:力扣题目链接
视频:代码随想录视频讲解
获取链表中下标为 index
的节点的值的简单写法:
while(index>0)
{
index--;
p=p->next;
}
return p->val;
需要注意以下几点:
1.构造函数的写法
2.定义结点的写法
3.函数间的调用
代码
class MyLinkedList {
public:
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
MyLinkedList() {
_dummyHead = new ListNode(0); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
size = 0;
}
int get(int index) {
if(index<0||index>size-1)
return -1;
ListNode* p=_dummyHead->next;
while(index>0)
{
index--;
p=p->next;
}
return p->val;
}
void addAtHead(int val) {
addAtIndex(0,val);
}
void addAtTail(int val) {
addAtIndex(size,val);
}
void addAtIndex(int index, int val) {
if (index < 0 || index > size) {
return;
}
ListNode* s=new ListNode(val);
ListNode* p=_dummyHead;
while(index>0)
{
index--;
p=p->next;
}
s->next=p->next;
p->next=s;
size++;
}
void deleteAtIndex(int index) {
if(index<0||index>size-1)
return;
ListNode* p=_dummyHead;
while(index>0)
{
index--;
p=p->next;
}
ListNode* q=p->next;
p->next=q->next;
delete q;
size--;
}
private:
int size;
ListNode* _dummyHead;
};
206.反转链表
题目:力扣题目链接
视频:代码随想录视频讲解
方法一:双指针
注意定义指针的写法。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre=nullptr;
ListNode* current=head;
ListNode* tempt;
while(current!=nullptr)
{
tempt=current->next;
current->next=pre;
pre=current;
current=tempt;
}
return pre;
}
};
方法二:递归
在打代码的过程中出现的问题:
问题在于递归调用 reverse 时没有正确处理返回值。此外,reverseList 和 reverse 函数的返回类型是 ListNode*,但在递归调用中没有正确返回翻转后的链表头。(函数与返回值要对应)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
return reverse(head,nullptr);
}
ListNode* reverse(ListNode* current,ListNode* pre)
{
ListNode* tempt;
if(current==nullptr)
return pre;
tempt=current->next;
current->next=pre;
return reverse(tempt,current);
}
};