代码随想录刷题2022.02.07
链表相关操作1
LeetCode题目1
解题要点
1)链表的实际指针过程可以简化理解为:
cur:当前节点地址;
cur->next:下一个节点地址;
cur->next->next:下下个节点地址;
注意:应当防止curNULL以及cur->nextNULL
2)对单向链表,由于只能得知后一个节点的信息,因此,移除元素时,应从该移除元素的上一个节点处开始;
3)创建节点指针时,应立刻初始化,或使用new()实现内存初始化;
代码过程
1)原链表分类删除法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
while(head!=NULL&&head->val==val){
head=head->next;
}
ListNode* cur=head;
while(cur!=NULL&&cur->next!=NULL){
if(cur->next->val==val){
cur->next=cur->next->next;
}
else
cur=cur->next;
}
return head;
}
};
2)虚拟节点法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyhead=new(ListNode);
dummyhead->next=head;
ListNode* cur=dummyhead;
while(cur!=NULL&&cur->next!=NULL)
{
if(cur->next->val==val){
cur->next=cur->next->next;
}
else
cur=cur->next;
}
return dummyhead->next;
}
};
LeetCode题目2
解题思路
1)用结构体struct定义(并初始化)链表;
2)当出现"第n个节点"时,定义一个“cur”指针来遍历链表,找到对应的第n个位置
LinkedNode* cur=_dummyhead->next;
while(index)
{
cur=cur->next;
index--;
}
3)添加节点或删除节点时,都从要添加的那个节点开始操作:
i)添加节点时,从要添加的那个节点开始先链接下个节点;
ii)删除节点时,先将要删除的那个节点进行复制,以备delete释放内存。
代码过程
class MyLinkedList {
public:
struct LinkedNode{
int val;
struct LinkedNode* next;
LinkedNode(int val):val(val),next(nullptr){}//结构体初始化
};
//类使用构造函数初始化;
MyLinkedList() {
_dummyhead = new LinkedNode(0); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
_size = 0;
}
//获取链表中第 index 个节点的值。如果索引无效,则返回-1。
int get(int index) {
if(index<0||index>(_size-1))return -1;
LinkedNode* cur=_dummyhead->next;
while(index)
{
cur=cur->next;
index--;
}
return cur->val;
}
//在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
void addAtHead(int val) {
LinkedNode* temp=new LinkedNode(val);
temp->next=_dummyhead->next;
_dummyhead->next=temp;
_size++;
}
//将值为 val 的节点追加到链表的最后一个元素.
void addAtTail(int val) {
LinkedNode* newnode=new LinkedNode(val);
LinkedNode* cur=_dummyhead;
while(cur->next!=NULL)
{
cur=cur->next;
}
cur->next=newnode;
_size++;
}
//在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
void addAtIndex(int index, int val) {
if(index>_size)return;
if(index<0)index=0;
LinkedNode* cur=_dummyhead;
while(index)
{
cur=cur->next;
index--;
}
LinkedNode* newnode=new LinkedNode(val);
newnode->next=cur->next;
cur->next=newnode;
_size++;
}
//如果索引 index 有效,则删除链表中的第 index 个节点。
void deleteAtIndex(int index) {
if(index<0||index>=_size)return;
LinkedNode* cur=_dummyhead;
while(index)
{
cur=cur->next;
index--;
}
LinkedNode* temp=cur->next;
cur->next=cur->next->next;
delete(temp);
_size--;
}
private:
int _size;
LinkedNode* _dummyhead;
};
/**
* 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);
*/
LeetCode题目3
解题思路
1)迭代法:初始条件+终止条件+迭代式
2)递归法:终止条件+初始条件+递归式(结合栈上函数的开始与结束来进行分析)
代码过程
1)迭代法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//初始条件
ListNode* cur=head;
ListNode* pre=NULL;
while(cur!=NULL)//终止条件
{
//迭代关系
ListNode* temp=cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
return pre;
}
};
2)迭代法(先向后遍历再向前遍历)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//特例情况
if(head==NULL)return NULL;
//终止条件
if(head->next==NULL){
return head;;
}
//先向前遍历再向后遍历,结合栈的特点进行分析
ListNode* last=reverseList(head->next);//初始条件
//递归式
ListNode* temp=head->next;
temp->next=head;
head->next=NULL;
return last;
}
};