203.移除链表元素
学习资料
题目链接/文章讲解/视频讲解::代码随想录
代码
没看解析前的解法,边界情况的处理有点复杂,绕了蛮久,并且没有手动释放删除的内存
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(head == nullptr) return nullptr;
ListNode* temp = head;
bool isFirst = true;
while(temp->next != nullptr){
if(isFirst && temp->val == val){
temp = temp->next;
head = temp;
continue;
}
isFirst = false;
if(temp->next->val == val){
if(temp->next->next != nullptr){
ListNode* store = temp->next->next;
temp->next = store;
}
else{
temp->next = nullptr;
break;
}
}
else{
temp = temp->next;
}
}
if(isFirst && temp->val == val){
head = nullptr;
}
return head;
}
};
看了解析后发现虚拟头结点可以将删除头结点和中间节点的代码统一起来,比较方便
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyNode = new ListNode(0);
dummyNode->next = head;
ListNode* temp = dummyNode;
while(temp->next != nullptr){
if(temp->next->val == val){
ListNode* store = temp->next;
temp->next = temp->next->next;
delete store;
}
else{
temp = temp->next;
}
}
head = dummyNode->next;
delete dummyNode;
return head;
}
};
同时了解到,delete和free,new和malloc的区别在于是否调用类的构造和析构函数
通过群友的建议改进了在栈上创建虚拟头结点的方式
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode dummyNode = ListNode(0);
dummyNode.next = head;
ListNode* temp = &dummyNode;
while(temp->next != nullptr){
if(temp->next->val == val){
ListNode* store = temp->next;
temp->next = temp->next->next;
delete store;
}
else{
temp = temp->next;
}
}
head = dummyNode.next;
return head;
}
};
代码
class MyLinkedList {
private:
struct LinkedNode{
int val;
LinkedNode* next;
LinkedNode():val(0),next(nullptr){};
};
int m_size;
LinkedNode* m_head;
public:
MyLinkedList():m_size(0){
m_head = new LinkedNode();
}
int get(int index) {
LinkedNode* temp = m_head;
while(index >= 0){
if(temp-> next == nullptr){
return -1;
}
temp = temp->next;
index--;
}
return temp->val;
}
void addAtHead(int val) {
LinkedNode* newNode = new LinkedNode();
newNode->next = m_head->next;
m_head->next = newNode;
newNode->val = val;
m_size++;
}
void addAtTail(int val) {
LinkedNode* temp = m_head;
LinkedNode* newNode = new LinkedNode();
newNode->val = val;
while(temp->next != nullptr){
temp = temp->next;
}
temp->next = newNode;
m_size++;
}
void addAtIndex(int index, int val) {
if(index > m_size) return;
LinkedNode* temp = m_head;
while(index > 0){
temp = temp->next;
index--;
}
LinkedNode* newNode = new LinkedNode();
newNode->val = val;
newNode->next = temp->next;
temp->next = newNode;
m_size++;
}
void deleteAtIndex(int index) {
if(index < 0 || index > m_size - 1) return;
LinkedNode* temp = m_head;
while(index > 0){
temp = temp->next;
index--;
}
LinkedNode* store = temp->next;
temp->next = temp->next->next;
delete store;
m_size--;
}
};
代码
看题解前自己写的代码,涉及三个指针,有两个处理头结点翻转的地方用了bool判断,不是很优雅
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == nullptr ||head->next == nullptr) return head;
ListNode* temp = head;
ListNode* store1 = temp->next;
ListNode* store2;
bool isFirst = true;
while(temp->next != nullptr){
if(store1->next == nullptr){
if(isFirst){
temp->next = nullptr;
isFirst = false;
}
store1->next = temp;
head = store1;
break;
}
else{
if(isFirst){
temp->next = nullptr;
isFirst = false;
}
store2 = store1->next;
store1->next = temp;
temp = store1;
store1 = store2;
store2 = store2->next;
}
}
return store1;
}
};
把左指针直接先指向空可以避免头结点判断
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == nullptr || head->next == nullptr) return head;
ListNode* left = nullptr;
ListNode* right = head;
ListNode* store;
while(store != nullptr){
store = right->next;
right->next = left;
left = right;
right = store;
}
return left;
}
};