链表理论基础
文章链接:代码随想录
今天复习链表的重心是查看它的c++ 实现
// 单链表
struct ListNode {
int val; // 节点上存储的元素
ListNode *next; // 指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数
};
可以看到和Java不同,C++会使用struct来构建类,指针来做引用。构造函数的写法也不一样。这才一下子反应过来之前在虚幻5写蓝图的时候撞见的struct到底是什么意思。
默认构造函数不能赋值 只能构造后再手动赋值。
删除时,需要手动释放节点,不会像java一样没有引用时自动垃圾回收。这大概是指针和引用的一种区别吧。
203.移除链表元素
建议: 本题最关键是要理解 虚拟头结点的使用技巧,这个对链表题目很重要。
题目链接/文章讲解/视频讲解:代码随想录
注意到有 ListNode *next; 和 ListNode* 两种用法,还没搞清楚具体怎么一回事,大概是只要是有关构造指针,都要把星号塞进去,但挨着ListNode 还是挨着 field name,影响不大。
/**
* 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* dummy = new ListNode();
dummy->next = head;
ListNode *curr = head;
ListNode *prev = dummy;
while (curr != nullptr) {
if (curr -> val == val) {
ListNode *temp = curr;
prev -> next = curr -> next;
curr = curr -> next;
delete temp;
} else {
prev = curr;
curr = curr -> next;
}
}
head = dummy->next;
delete dummy;
return head;
}
};
看上去有冗余,是因为之前出了bug修成这样的。我没意识到delete temp之后,current就会无东西可指。所以delete是一定得在把指针挪走之后的。
707.设计链表
建议: 这是一道考察 链表综合操作的题目,不算容易,可以练一练 使用虚拟头结点
题目链接/文章讲解/视频讲解:代码随想录
看上去要多花点时间才能写完这个 今天先跳过 回头补上
206.反转链表
建议先看我的视频讲解,视频讲解中对 反转链表需要注意的点讲的很清晰了,看完之后大家的疑惑基本都解决了。
题目链接/文章讲解/视频讲解:代码随想录
/**
* 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 *prev = nullptr;
ListNode *curr = head;
while (curr != nullptr) {
head = curr;
curr = curr -> next;
head -> next = prev;
prev = head;
}
return head;
}
};
写了这样的code,发现自己老是把 "->" 写成 ".",眼睛还不觉得有问题导致了几次编译报错, 只能多多习惯了。
还发现代码随想录使用了prev=null, 但这里写空指针nullptr也可以,之后要再仔细看看。
目前使用了1.5h,还差一题,之后补上