代码随想录算法训练营day03|203.移除链表元素,707.设计链表,206.反转链表
1.代码随想录算法训练营day01|704. 二分查找,27. 移除元素,977.有序数组的平方2.代码随想录算法训练营day02|209.长度最小的子数组,59.螺旋矩阵II
3.代码随想录算法训练营day03|203.移除链表元素,707.设计链表,206.反转链表
4.代码随想录算法训练营day04|24.两两交换链表中的节点,19.删除链表的倒数第N个节点,面试题 02.07.链表相交,142.环形链表II5.代码随想录算法训练营day06|242.有效的字母异位词,349.两个数组的交集,202.快乐数,1.两数之和6.代码随想录算法训练营day07|454.四数相加II,383.赎金信,15.三数之和,18.四数之和7.代码随想录算法训练营day08|344.反转字符串,541.反转字符串II,卡码网:54.替换数字8.代码随想录算法训练营day09|151.翻转字符串里的单词,卡码网:55.右旋转字符串,28.实现 strStr(),459.重复的子字符串203.移除链表元素
题目链接:https://leetcode.cn/problems/remove-linked-list-elements/description/
我的代码(分头节点和中间节点两种情况操作):
/** * 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 != nullptr && head->val == val) { ListNode* q = head; head = head->next; delete q; } ListNode* p = head; while (p != nullptr && p->next != nullptr) { if (p->next->val == val) { ListNode* q = p->next; p->next = q->next; delete q; } else p = p->next; } return head; } };
头节点操作:直接后移头节点并将原来的头节点内存释放。
中间节点操作:检测到当前节点后一个节点的数据域等于索引值时,将当前节点的指针域指向后一个节点的后一个节点,然后释放后一个节点的内存,否则后移当前节点。
虚拟头节点(所有节点按一种方法操作):
/** * 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_head = new ListNode; dummy_head->next = head; ListNode* current = dummy_head; while (current->next != nullptr) { if (current->next->val == val) { ListNode* temp = current->next; current->next = current->next->next; delete temp; } else current = current->next; } head = dummy_head->next; delete dummy_head; return head; } };
在原链表的头节点之前再加一个实际上不存储数据的虚拟头节点,方便操作。
707.设计链表
题目链接:https://leetcode.cn/problems/design-linked-list/description/
我的代码:
class MyLinkedList { public: struct LinkedList { int val; struct LinkedList* next; LinkedList(int val) : val(val), next(nullptr) {} }; MyLinkedList() { dummy_head = new LinkedList(0); size = 0; } int get(int index) { if (index < size && index >= 0) { LinkedList* p = dummy_head->next; while (index > 0) { index--; p = p->next; } return p->val; } else return -1; } void addAtHead(int val) { LinkedList* p = new LinkedList(val); p->next = dummy_head->next; dummy_head->next = p; size++; } void addAtTail(int val) { LinkedList* p = new LinkedList(val); LinkedList* q = dummy_head; int length = size; while (length > 0) { length--; q = q->next; } q->next = p; p->next = nullptr; size++; } void addAtIndex(int index, int val) { if (index >= 0 && index < size) { LinkedList* p = new LinkedList(val); LinkedList* q = dummy_head; while (index > 0) { index--; q = q->next; } p->next = q->next; q->next = p; size++; } else if (index == size) { LinkedList* p = new LinkedList(val); LinkedList* q = dummy_head; while (index > 0) { index--; q = q->next; } q->next = p; p->next = nullptr; size++; } } void deleteAtIndex(int index) { LinkedList* p = dummy_head; if (index < size && index >= 0) { while (index > 0) { index--; p = p->next; } LinkedList* q = p->next; p->next = q->next; delete q; size--; } } private: LinkedList* dummy_head; int size; }; /** * 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); */
206.反转链表
题目链接:https://leetcode.cn/problems/reverse-linked-list/description/
双指针解法:
/** * 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* pre = nullptr; ListNode* current = head; while (current != nullptr) { ListNode* temp = current->next; current->next = pre; pre = current; current = temp; } return pre; } };
pre:开始定义为头节点前的空指针。
current:开始定义为头节点。
每次循环使用temp暂存current的next节点,然后使current的next指针指向pre,pre和current都后移,最后当current指向尾节点后的空指针时结束循环,返回当前真正头节点pre。
递归解法:
/** * 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) { return reverse(nullptr, head); } ListNode* reverse(ListNode* pre, ListNode* current) { if (current == nullptr) return pre; ListNode* temp = current->next; current->next = pre; return reverse(current, temp); } };
与双指针解法思路相同。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!