【数据结构/链表】题解+备注
- 203.移除链表元素
- 707.设计链表
- 206.翻转链表
- 24.两两交换链表中的节点
- 19.删除链表的倒数第N个节点
- 07.链表相交
- 142.环形链表II
- 21.合并两个有序链表
- 23.合并K个升序链表
- 25.K个一组翻转链表
- 61.旋转链表
- 82.删除排序链表中的重复元素
- 83.删除排序链表中的重复元素
- 86.分隔链表
- 92.反转链表II
- 109.有序链表转换二叉搜索树
- 114.二叉树展开为链表
- 138.复制带随机指针的链表
- 141.环形链表
- 143.重排链表
- 146.LRU缓存机制
- 147.对链表进行插入排序
- 148.排序链表
- 160.相交链表
- 234.回文链表
- 237.删除链表中的节点
- 706.设计哈希映射
- 641.设计循环双端队列
- 622.设计循环队列
- 876.链表的中间节点
- 2058.找出临界点之间的最小和最大距离
- 2074.反转偶数长度组的节点
- 2095.删除链表的中间节点
203.移除链表元素
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// 声明虚拟头节点
ListNode* temp = new ListNode(0);
temp->next = head;
// 寻找删除节点、删除
ListNode*cur = temp;
while(cur->next != nullptr){
if(cur->next->val == val){
cur->next = cur->next->next;
}else{
cur = cur->next;
}
}
return temp->next;
}
};
707.设计链表
class MyLinkedList {
public:
// 声明链表结构
struct LinkedNode{
int val{};
LinkedNode* next{nullptr};
LinkedNode(int inVal): val(inVal){}
};
MyLinkedList() {
// 初始化虚拟头节点
m_dummyNode = new LinkedNode(0);
}
int get(int index) {
if(index > (m_size -1) || index < 0) return -1;
// 根据index寻找节点
LinkedNode* cur = m_dummyNode->next;
while(index--){
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
LinkedNode* node = new LinkedNode(val);
//直接插入头节点
node->next = m_dummyNode->next;
m_dummyNode->next = node;
m_size++;
}
void addAtTail(int val) {
LinkedNode *tail = new LinkedNode(val);
// 先移动到尾节点、然后添加新增节点
LinkedNode *cur = m_dummyNode;
while(cur->next != nullptr){
cur = cur->next;
}
cur->next = tail;
m_size++;
}
void addAtIndex(int index, int val) {
if(index > m_size) return;
LinkedNode* node = new LinkedNode(val);
LinkedNode* cur = m_dummyNode;
// 移动到index节点处
while(index--&& cur != nullptr){
cur = cur->next;
}
// 插入节点
node->next = cur->next;
cur->next = node;
m_size++;
}
void deleteAtIndex(int index) {
if(index > m_size-1 || index < 0) return;
LinkedNode* cur = m_dummyNode;
// 移动到index节点处
while(index--&& cur != nullptr){
cur = cur->next;
}
// 删除节点
LinkedNode* temp= cur->next;
if(cur->next != nullptr)cur->next = cur->next->next;
m_size--;
}
private:
int m_size{};
LinkedNode *m_dummyNode { nullptr };
};
206.翻转链表
class Solution {
public:
// 递归求解
ListNode* reverse(ListNode* pre,ListNode* cur){
if(cur == nullptr) return pre;
ListNode* temp = cur->next;
cur->next = pre;
return reverse(cur,temp);
}
ListNode* reverseList(ListNode* head) {
// 双指针求解
// ListNode* cur = head;
// ListNode* pre = nullptr;
// while(cur){
// ListNode* temp = cur->next;
// cur->next = pre;
// pre = cur;
// cur = temp;
// }
// return pre;
return reverse(nullptr,head);
}
};
24.两两交换链表中的节点
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
// 先声明虚拟头节点
ListNode* dummyNode = new ListNode(0);
dummyNode->next = head;
ListNode* cur = dummyNode;
while(cur->next!=nullptr && cur->next->next != nullptr){
ListNode* temp = cur->next;
ListNode* temp1 = cur->next->next->next;
// 节点交换
cur->next = cur->next->next;
cur->next->next = temp;
temp->next = temp1;
// 赋值为需要交换的下两个节点的首个节点
cur = cur->next->next;
}
return dummyNode->next;
}
};
19.删除链表的倒数第N个节点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
// 应用双指针
ListNode* dummpyNode = new ListNode(0);
dummpyNode->next = head;
ListNode* slowNode = dummpyNode;
ListNode* fastNode = dummpyNode;
// 先移动n个节点
while(n-- && fastNode != nullptr) fastNode = fastNode->next;
// 双指针寻找倒数第n个节点
fastNode = fastNode->next;
while(fastNode != nullptr){
slowNode = slowNode->next;
fastNode = fastNode->next;
}
// 删除节点
slowNode->next = slowNode->next->next;
return dummpyNode->next;
}
};
07.链表相交
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
// 计算两个链表的长度
int lenA{},lenB{};
ListNode* curA = headA;
ListNode* curB = headB;
while(curA!=nullptr){
lenA++;
curA = curA->next;
}
while(curB != nullptr){
lenB++;
curB = curB->next;
}
curA = headA;
curB = headB;
// lenA表示为最长的链表长度,curA为最长的链表头节点
if(lenB > lenA){
swap(lenA,lenB);
swap(curA,curB);
}
// 最长节点先移动长度差个节点
int delta = lenA - lenB;
while(delta--){
curA = curA->next;
}
// 判断链表是否会相交
while(curA!=nullptr){
if(curB == curA) return curB;
curB = curB->next;
curA = curA->next;
}
return {};
}
};
142.环形链表II
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
// 应用双指针
if(!head) return{};
ListNode* slow = head;
ListNode* fast = head;
while(fast->next!=nullptr && fast->next->next!=nullptr){
slow = slow->next;
fast = fast->next->next;
// 如果快慢指针相遇,说明有环
if(slow == fast){
slow = head;
// 公式推导查看具体题解
while(slow != fast){
slow = slow->next;
fast = fast->next;
}
return slow;
}
}
return {};
}
};
21.合并两个有序链表
class Solution {
public:
// 递归实现
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(!l1) return l2;
if(!l2) return l1;
ListNode* ans;
if(l1->val <= l2->val){
ans = l1;
l1 = l1->next;
}else{
ans = l2;
l2 = l2->next;
}
ans->next = mergeTwoLists(l1,l2);
return ans;
}
};
23.合并K个升序链表
25.K个一组翻转链表
61.旋转链表
82.删除排序链表中的重复元素
83.删除排序链表中的重复元素
86.分隔链表
92.反转链表II
109.有序链表转换二叉搜索树
114.二叉树展开为链表
138.复制带随机指针的链表
141.环形链表
143.重排链表
146.LRU缓存机制
147.对链表进行插入排序
148.排序链表
160.相交链表
234.回文链表
237.删除链表中的节点
706.设计哈希映射
641.设计循环双端队列
622.设计循环队列
876.链表的中间节点
2058.找出临界点之间的最小和最大距离
2074.反转偶数长度组的节点
2095.删除链表的中间节点