203. 移除链表元素 - 力扣(LeetCode)https://leetcode.cn/problems/remove-linked-list-elements/203和206都是以前刷过的,但是隔了好久再做时候,细节还是会有一点问题,链表问题大多都可以用虚拟头结点的方法,使链表的插入和删除操作变得简单。
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode dummyhead;
dummyhead.next=head;
ListNode* cur=&dummyhead;
while(cur&&cur->next)
{
if(cur->next->val==val){
ListNode*tmp=cur->next;
cur->next=cur->next->next;
delete tmp;
}
else
cur=cur->next;
}
return dummyhead.next;
}
};
这道题并不难,值得注意的是,创建一个临时指针,指向head,然后判断它的值是否等于val,要注意的是用cur->next->val来判断值是否是我们需要找的,如果是的话,cur指向的正是要删除节点的上一个节点,直接将cur的next指针连到要删除节点的下一个位置就可以了,这是非常重要的思路要删除节点的上一个节点要能够被找到。如果不是正常指向下一个节点就可以了,思路清晰很容易ac。
206. 反转链表 - 力扣(LeetCode)https://leetcode.cn/problems/reverse-linked-list/反转链表更是老生常谈的话题了,之前链表做过的第一道题就是反转链表,不过那时候是在牛客。
思路明确的同时还要注意head指针传进来时,若是空的情况要怎么处理,以及应该创建几个临时节点,分别保存什么。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL)return head;
ListNode* next=head->next;
ListNode* ret=NULL;
ListNode* cur=head;
while(cur)
{
cur->next=ret;
ret=cur;
cur=next;
if(next)
next=next->next;
}
return ret;
}
};
要明确的是创立三个临时指针,一个用来保存要反转的节点的下一个链接节点,一个用来指向下一个反转节点的next连接到哪里,另一个代表当前要反转的节点。缺一不可的,一开始ret要指向null,使第一个反转的链表有指向的指针,只要明确要用到几个指针,以及分别初始化为什么值,这道题就很容易解的出来了。
递归代码也给出,和上面的方法思路是相同的,不做赘述。
class Solution {
public:
ListNode* reverse(ListNode* cur,ListNode* pre)
{
if(cur==NULL)return pre;
ListNode* temp=cur->next;
cur->next=pre;
return reverse(temp,cur);
}
ListNode* reverseList(ListNode* head) {
return reverse(head,nullptr);
}
};
707. 设计链表 - 力扣(LeetCode)https://leetcode.cn/problems/design-linked-list/设计链表是一道综合题,涵盖了很多有关于链表的函数接口,适合练习,整体思路不算很难,但是对于我这个c++初学者,有蛮多语法细节搞不太懂(之前主要是写c的)
class MyLinkedList {
public:
struct LinkNode{
int val;
LinkNode* next;
LinkNode(int val):val(val),next(nullptr){}
};
MyLinkedList() {
dummyhead=new LinkNode(0);
size=0;
}
int get(int index) {
if(index<0)return -1;
else if(index>size-1)return -1;
LinkNode*cur=dummyhead->next;
while(index--){
cur=cur->next;
}
return cur->val;
}
void addAtHead(int val) {
LinkNode*cur=dummyhead;
LinkNode* tmp=new LinkNode(val);
tmp->next=cur->next;
cur->next=tmp;
size++;
}
void addAtTail(int val) {
LinkNode*cur=dummyhead;
LinkNode* tmp=new LinkNode(val);
while(cur->next){
cur=cur->next;
}
cur->next=tmp;
size++;
}
void addAtIndex(int index, int val) {
LinkNode*cur=dummyhead;
if(index==size){
addAtTail(val);return;
}
else if(index>size)return;
else if(index<0){
addAtHead(val);return;
}
while(index--){
cur=cur->next;
}
LinkNode* tmp=new LinkNode(val);
tmp->next=cur->next;
cur->next=tmp;size++;
}
void deleteAtIndex(int index) {
LinkNode*cur=dummyhead;
if(index>=size||index<0)return;
while(index--){
cur=cur->next;
}
cur->next=cur->next->next;
size--;
}
private :
int size;
LinkNode* dummyhead;
};
起初写的时候很懵逼,还在想为什么没有给头节点指针,而是只有index?后来看题解才知道要自己创建结构体,和虚拟头节点(方便空链表插入)。但是对于结构体里的构造函数的创建,和最后虚拟节点才进行数据类型的定义还是有些许不理解,应该取看看语法了。。。
回归主题,整体思路难度适中,只是接口多了一些,思路清晰还是能写出得出来的。
代码均可ac,有用记得三连哦!!