文档>链表理论
203.移除链表元素 >移除链表707.设计链表 >设计链表 | 结构体
206.反转链表 >反转链表 双指针|递归
203.移除链表元素
第一想法
如果该节点的下一个节点等于val,需要将其next指针指向下一个的下一个节点,要循环比较有可能一直是等于val的.注意第一个节点也有可能等于val,因此需要插入一个虚拟头节点.
存在问题
是否需要把虚拟头节点内存释放掉,想要释放可以把head先赋值,然后`delete dummy`.
代码
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
auto dummy = new ListNode(-1);
dummy->next = head;
auto cur = dummy;
if (!head) return nullptr;
while (cur != nullptr && cur->next != nullptr){
while (cur->next != nullptr && cur->next->val == val) cur->next = cur->next->next;
cur = cur->next;
}
return dummy->next;
}
};
707.设计链表
第一想法
其实是对链表操作的回顾,主要是整个类需要自己写,需要对面向对象有所了解.
解题思路
已给的结构中给出了方法,因此要向其中填充 data和method的实现.
- data:链表的大小size和加入的虚拟头节点,还要定义ListNode的结构体
- method:主要要注意index是从0开始,也就是说size为3的时候,最后的index是2.
- 删除节点的时候,可以建立一个临时指针指向要跳过的节点,然后把它释放掉.
class MyLinkedList {
public:
struct ListNode {
int val;
ListNode* next;
ListNode(int x): val(x), next(nullptr){}
};
MyLinkedList() {
dummy = new ListNode(-1);
size = 0;
}
int get(int index) {
if (index >= size || index < 0) return -1;
auto cur = dummy;
while (index --) cur = cur->next;
return cur->next->val;
}
void addAtHead(int val) {
ListNode* node = new ListNode(val);
node->next = dummy->next;
dummy->next = node;
size ++;
}
void addAtTail(int val) {
ListNode* node = new ListNode(val);
auto cur = dummy;
while (cur->next != nullptr) cur = cur->next;
cur->next = node;
size ++;
}
void addAtIndex(int index, int val) {
if (index > size) return;
if (index < 0) index = 0;
ListNode* node = new ListNode(val);
auto cur = dummy;
while (index --) cur = cur->next;
node->next = cur->next;
cur->next = node;
size ++;
}
void deleteAtIndex(int index) {
if (index >= size || index < 0) return;
auto cur = dummy;
while (index --) cur = cur->next;
cur->next = cur->next->next;
size --;
}
private:
ListNode* dummy;
int size;
};
206.反转链表
第一想法
每两个相邻的节点进行反转,注意什么时候循环截止.同时要判断空链表,或者只有一个节点的时候.
解题思路
1. 双指针:同上
2. 递归:因为是循环操作,可以变为递归
代码
1. 双指针
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head || !head->next) return head;
auto a = head, b = head->next;
while (b != nullptr){
auto c = b->next;
b->next = a;
a = b;
b = c;
}
head->next = nullptr;
return a;
}
};
2. 递归
class Solution {
public:
ListNode* reverseList(ListNode* head) {
return reverse(nullptr, head);
}
ListNode* reverse(ListNode* pre, ListNode* cur){
if (cur == nullptr) return pre;
auto c = cur->next;
cur->next = pre;
return reverse(cur, c);
}
};