目录
- 前言
- [1.力扣——876. 链表的中间结点](https://leetcode.cn/problems/middle-of-the-linked-list/description/)
- [2.力扣——面试题 02.02. 返回倒数第 k 个节点](https://leetcode.cn/problems/kth-node-from-end-of-list-lcci/description/)
- [3.力扣——203. 移除链表元素](https://leetcode.cn/problems/remove-linked-list-elements/description/)
- [4.力扣——237. 删除链表中的节点](https://leetcode.cn/problems/delete-node-in-a-linked-list/description/)
- [5.力扣——83. 删除排序链表中的重复元素](https://leetcode.cn/problems/remove-duplicates-from-sorted-list/)
- [6.力扣——19. 删除链表的倒数第 N 个结点](https://leetcode.cn/problems/remove-nth-node-from-end-of-list/description/)
- [力扣——7.面试题 02.01. 移除重复节点](https://leetcode.cn/problems/remove-duplicate-node-lcci/)
- 结语
前言
这个题库是用于学完单向链表数据结构来进行训练巩固知识点的,所以没学到单向链表的看我这个作品的内容。(点蓝色字体进去看以前那个作品)
1.力扣——876. 链表的中间结点
蓝色字体可以点进去看原题
/**
* 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* middleNode(ListNode* head) {//这题主要思路就是快慢指针,快的走两步慢的走一步
//节点个数可能为奇数也可能为偶数,所以快指针每走一步要判断是否为空,如果为空中间节点所在位置就是慢指针位置
ListNode*fast=head;
ListNode*slow=head;
while(fast){
fast=fast->next;
if(!fast)return slow;//快指针走一步以后如果快指针所在位置为空,那就是链表已经到头了
fast=fast->next;
if(!fast)return slow->next;
slow=slow->next;
}
return slow;
}
};
2.力扣——面试题 02.02. 返回倒数第 k 个节点
蓝色字体可以点进去看原题
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
int kthToLast(ListNode* head, int k) {//这题解题思路仍然是快慢指针,快指针先走k步,然后快慢指针一起走,直到快指针为空,也就是链表跑完了,此时慢指针的位置就是倒数第k个节点
ListNode*fast=head;
ListNode*slow=head;
while(k--){
fast=fast->next;
}
while(fast){
fast=fast->next;
slow=slow->next;
}
return slow->val;
}
};
3.力扣——203. 移除链表元素
蓝色字体可以点进去看原题
/**
* 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*newHead=new ListNode();//申请虚拟内存空间,因为要修改链表,所以返回从它的下一个节点开始的链表
newHead->next=head;
ListNode*pre=newHead;
while(pre->next){//从pre的下一个节点也就是head节点开始遍历
if(pre->next->val==val){
pre->next=pre->next->next;
}
else pre=pre->next;
}
return newHead->next;
}
};
4.力扣——237. 删除链表中的节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
node->val=node->next->val;//将该节点的值覆盖为下一个节点的值
node->next=node->next->next;//再将该节点下一个节点指向该节点的下下个节点
}
};
5.力扣——83. 删除排序链表中的重复元素
/**
* 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* deleteDuplicates(ListNode* head) {//这道题必须得有前序节点和后继结点,前驱等于后继那么一定要有修改
ListNode*curr=head;
ListNode*pre=NULL;
while(curr){
while(pre&&pre->val==curr->val){//pre刚开始为空节点所以循环条件要加上pre不为空,因为重复的节点可能会一直相邻所以要循环判断
pre->next=curr->next;
curr=pre->next;
if(!curr)break;//因为curr如果为空就没必要再循环下去了,并且curr如果为空在进行循环curr->val会报错
}
if(!curr)break;
pre=curr;
curr=curr->next;
}
return head;
}
};
6.力扣——19. 删除链表的倒数第 N 个结点
/**
* 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* removeNthFromEnd(ListNode* head, int n) {
ListNode*fast=head;
ListNode*slow=head;
ListNode*pre=NULL;//pre作为slow的前驱节点
while(n--) fast=fast->next;
while(fast){
pre=slow;
slow=slow->next;
fast=fast->next;
}
if(!pre)return head->next;//可能删除的是倒数第n个节点,也就是第一个节点所以pre为空
pre->next=slow->next;
return head;
}
};
力扣——7.面试题 02.01. 移除重复节点
这一题和上面第五题差不多的思路,就是要用哈希表
/**
* 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* removeDuplicateNodes(ListNode* head) {//运用哈希表映射
if(head==NULL)return NULL;
int hash[20001]={0};
hash[head->val]=1;//头结点第一次出现
ListNode*curr=head;
ListNode*pre=NULL;
while(curr){
while(pre&&hash[curr->val]){
pre->next=curr->next;
curr=pre->next;
if(!curr)break;
}
if(!curr)break;
hash[curr->val]=1;//如果这个值没出现过就赋值为1,就代表已经出现过了
pre=curr;
curr=curr->next;
}
return head;
}
};
结语
还没完今天就更到这,下个作品我会更反转链表等一些有难度的题
想看更多内容可以关注我,看我作品,关注我让我们一起学习编程,希望大家能点赞关注支持一下,让我有持续更新的动力,谢谢大家。