Leetcode 203.移除链表元素
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyhead = new ListNode (0, head);
ListNode* temp = dummyhead;
while (temp->next != nullptr)
{
if (temp->next->val == val)
{
temp->next = temp->next->next;
// 上一步操作之后,temp->next就是新的了,并没有判断过,所以不要这一步
// temp = temp->next;
}
else
{
temp = temp->next;
}
}
return dummyhead->next;
}
};
dummyhead的作用为保存头节点的位置,因为头节点可能会被删除
创建一个临时节点temp, 当temp的next为空时即停止遍历,不用考虑temp现在是否等于val,因为在上一级已经考虑过temp会等于val的情况了
Leetcode 707.设计链表
class MyLinkedList {
public:
typedef struct _node {
int val;
_node* next;
_node(int val):val(val), next(nullptr) {}
} Node;
Node* dummyhead;
int size;
// 这不是一个节点,这是一个类的构造函数
MyLinkedList() {
dummyhead = new Node(0); // 虚拟头节点, 不是真正的头节点
size = 0;
//printLinedList();
//cout << size << endl;
}
int get(int index) {
if (index < 0 || index > (size-1)) return -1;
Node* curr = dummyhead->next;
// cout << curr->val << endl;
for (int i = 0; i < index; i++) curr = curr->next;
return curr->val;
}
void addAtHead(int val) {
Node* newNode = new Node(val);
newNode->next = dummyhead->next;
dummyhead->next = newNode;
size++;
//printLinedList();
//cout << size << endl;
}
void addAtTail(int val) {
Node* curr = dummyhead;
Node* newtail = new Node(val);
while (curr->next != nullptr) curr = curr->next;
curr->next = newtail;
size++;
//printLinedList();
//cout << size << endl;
}
void addAtIndex(int index, int val) {
if (index > size) return;
if (index < 0) index = 0;
// 使用dummyhead 这样遍历的时候能够找到前一个node
// 不用考虑dummyhead会不会溢出,因为有size能够得到链表的大小
Node* temp = dummyhead;
for (int i = 0; i < index; i++) temp = temp->next;
// 如果index = size,那么此时temp是最后一个节点,temp的下一个节点为空节点
// 先记录temp的下一个节点,无论这个节点是不是空节点, temp的下一个节点就是第index个节点
Node* curr = temp->next;
Node* newnode = new Node(val);
newnode->next = curr;
temp->next = newnode;
size++;
//printLinedList();
//cout << size << endl;
}
void deleteAtIndex(int index) {
if (index < 0 || index >= size) return;
// 使用dummyhead 找到第index-1个node
Node* temp = dummyhead;
for (int i = 0; i < index; i++) temp = temp->next;
Node* curr = temp->next;
temp->next = curr->next;
delete curr;
size--;
}
void printLinedList()
{
Node* curr = dummyhead->next;
while (curr != nullptr)
{
cout << curr->val << " ";
curr = curr->next;
}
cout << endl;
}
};
使用dummyhead可以找到curr的前一个node
在使用循环遍历寻找第index个node时,使用dummyhead找到了第index-1个node
当index < 0时,直接index = 0, 初始想法为用if判断,逻辑全部展开,不用如此复杂,可以简化
找到第index个node,同时涉及到需要操作第index-1个node时, 可以直接找第index-1个node, 简化操作,第index个就是第index-1个的下一个
写for循环里的判断条件要注意每个值意义
Leetcode 206.反转链表
初见想法:递归或者迭代
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre = nullptr;
ListNode* cur = head;
// 链表可以先画个图
while (cur != nullptr)
{
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
遍历链表,curr不断的指向pre,当cur为空时就结束
链表题可以画一个图
class Solution {
public:
ListNode* reverseList(ListNode* head) {
return traversal(nullptr, head);
}
// 根据遍历法,推算得出
ListNode* traversal(ListNode* pre, ListNode* curr)
{
if (curr == nullptr) return pre;
ListNode* temp = curr->next;
curr->next = pre;
return traversal(curr, temp);
}
};
// 递归操作
traversal(....)
{
// 终止条件
// 操作
// traversal(....) 下一层
}
// 这种写法先操作,在往下一层去,有点类似遍历,直到终止条件停止
traversal(....)
{
// 终止条件
// traversal(......) 下一层
// 操作
}
// 这种写法为先到最底层再操作
递归函数先递归到最底层,然后最底层的最先返回
利用 return 来进入下一层, 无法确定 traversal的返回值时, 直接return, 只会返回一个值