文章目录
- [21. 合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/)
- [19. 删除链表的倒数第 N 个结点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)
- [2. 两数相加](https://leetcode-cn.com/problems/add-two-numbers/)
- [24. 两两交换链表中的节点](https://leetcode-cn.com/problems/swap-nodes-in-pairs/)
- [206. 反转链表](https://leetcode-cn.com/problems/reverse-linked-list/)
- [141. 环形链表](https://leetcode-cn.com/problems/linked-list-cycle/)
- [剑指 Offer 22. 链表中倒数第k个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/)
- [25. K 个一组翻转链表](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/)
- [23. 合并K个升序链表](https://leetcode-cn.com/problems/merge-k-sorted-lists/)
- [剑指 Offer 06. 从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/)
- [92. 反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/)
- [61. 旋转链表](https://leetcode-cn.com/problems/rotate-list/)
- [234. 回文链表](https://leetcode-cn.com/problems/palindrome-linked-list/)
- [160. 相交链表](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/)
- [83. 删除排序链表中的重复元素](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/)
- [142. 环形链表 II](https://leetcode-cn.com/problems/linked-list-cycle-ii/)
- [203. 移除链表元素](https://leetcode-cn.com/problems/remove-linked-list-elements/)
- [876. 链表的中间结点](https://leetcode-cn.com/problems/middle-of-the-linked-list/)
- [剑指 Offer 18. 删除链表的节点](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/)
- [146. LRU 缓存机制](https://leetcode-cn.com/problems/lru-cache/)
- [148. 排序链表](https://leetcode-cn.com/problems/sort-list/)
- [86. 分隔链表](https://leetcode-cn.com/problems/partition-list/)
- [328. 奇偶链表](https://leetcode-cn.com/problems/odd-even-linked-list/)
- [138. 复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer/)
对于链表类题目,一般是有一些套路的。
新建链表类型题目的套路:
这一类满满的套路,对指针的理解要求比较深入,如果不没总结过套路的话,肯定一脸懵逼……
- 首先new一个头指针 ListNode* head = newListNode(0);
- 然后定义一个当前结点,并指向头指针 ListNode* cur = head;
- 接下来对cur结点进行操作;
- 每次一顿操作完之后记得将 cur = cur->next,链表前进,否则最后得到的答案只有一个结点!
- 最后因为当前结点是指向head的指针,所以最后返回的是 head->next 才是想要的答案!返回cur或者head都是错误的!
21. 合并两个有序链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ux7cp8bi-1631410080337)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905170645075.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CnO95sQb-1631410080339)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905170953580.png)]
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l1 == nullptr) {
return l2;
} else if (l2 == nullptr) {
return l1;
} else if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2M02bxdB-1631410080340)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905171310198.png)]
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* preHead = new ListNode(-1);
ListNode* prev = preHead;
while (l1 != nullptr && l2 != nullptr) {
if (l1->val < l2->val) {
prev->next = l1;
l1 = l1->next;
} else {
prev->next = l2;
l2 = l2->next;
}
prev = prev->next;
}
// 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
prev->next = l1 == nullptr ? l2 : l1;
return preHead->next;
}
};
19. 删除链表的倒数第 N 个结点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sfyEpXNQ-1631410080341)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905171900612.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xqhWsQGB-1631410080341)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905172040030.png)]
int getLength(struct ListNode* head) {
int length = 0;
while (head) {
++length;
head = head->next;
}
return length;
}
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0, dummy->next = head;
int length = getLength(head);
struct ListNode* cur = dummy;
for (int i = 1; i < length - n + 1; ++i) {
cur = cur->next;
}
cur->next = cur->next->next;
struct ListNode* ans = dummy->next;
free(dummy);
return ans;
}
-----------------------------------------------------------------
/**
* 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:
int getLength(ListNode* head) {
int length = 0;
while (head) {
++length;
head = head->next;
}
return length;
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy = new ListNode(0, head);
int length = getLength(head);
ListNode* cur = dummy;
for (int i = 1; i < length - n + 1; ++i) {
cur = cur->next;
}
cur->next = cur->next->next;
ListNode* ans = dummy->next;
delete dummy;
return ans;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4ddtjT5a-1631410080342)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905172302647.png)]
struct Stack {
struct ListNode* val;
struct Stack* next;
};
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0, dummy->next = head;
struct Stack* stk = NULL;
struct ListNode* cur = dummy;
while (cur) {
struct Stack* tmp = malloc(sizeof(struct Stack));
tmp->val = cur, tmp->next = stk;
stk = tmp;
cur = cur->next;
}
for (int i = 0; i < n; ++i) {
struct Stack* tmp = stk->next;
free(stk);
stk = tmp;
}
struct ListNode* prev = stk->val;
prev->next = prev->next->next;
struct ListNode* ans = dummy->next;
free(dummy);
return ans;
}
---------------------------------------------------------------------
/**
* 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* dummy = new ListNode(0, head);
stack<ListNode*> stk;
ListNode* cur = dummy;
while (cur) {
stk.push(cur);
cur = cur->next;
}
for (int i = 0; i < n; ++i) {
stk.pop();
}
ListNode* prev = stk.top();
prev->next = prev->next->next;
ListNode* ans = dummy->next;
delete dummy;
return ans;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1KHK0Drz-1631410080343)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905172356807.png)]
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0, dummy->next = head;
struct ListNode* first = head;
struct ListNode* second = dummy;
for (int i = 0; i < n; ++i) {
first = first->next;
}
while (first) {
first = first->next;
second = second->next;
}
second->next = second->next->next;
struct ListNode* ans = dummy->next;
free(dummy);
return ans;
}
---------------------------------------------------------------
/**
* 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* dummy = new ListNode(0, head);
ListNode* first = head;
ListNode* second = dummy;
for (int i = 0; i < n; ++i) {
first = first->next;
}
while (first) {
first = first->next;
second = second->next;
}
second->next = second->next->next;
ListNode* ans = dummy->next;
delete dummy;
return ans;
}
};
2. 两数相加
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MDVCfGZa-1631410080344)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905172714235.png)]
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head = NULL, *tail = NULL;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 + carry;
if (!head) {
head = tail = malloc(sizeof(struct ListNode));
tail->val = sum % 10;
tail->next = NULL;
} else {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = sum % 10;
tail = tail->next;
tail->next = NULL;
}
carry = sum / 10;
if (l1) {
l1 = l1->next;
}
if (l2) {
l2 = l2->next;
}
}
if (carry > 0) {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = carry;
tail->next->next = NULL;
}
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* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *head = nullptr, *tail = nullptr;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val: 0;
int n2 = l2 ? l2->val: 0;
int sum = n1 + n2 + carry;
if (!head) {
head = tail = new ListNode(sum % 10);
} else {
tail->next = new ListNode(sum % 10);
tail = tail->next;
}
carry = sum / 10;
if (l1) {
l1 = l1->next;
}
if (l2) {
l2 = l2->next;
}
}
if (carry > 0) {
tail->next = new ListNode(carry);
}
return head;
}
};
24. 两两交换链表中的节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-clARU6jS-1631410080344)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905200722159.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ckZRTkPl-1631410080345)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905200812085.png)]
struct ListNode* swapPairs(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* newHead = head->next;
head->next = swapPairs(newHead->next);
newHead->next = head;
return newHead;
}
-----------------------------------------------------------------
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
ListNode* newHead = head->next;
head->next = swapPairs(newHead->next);
newHead->next = head;
return newHead;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ahmc7Tm-1631410080345)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905201103933.png)]
struct ListNode* swapPairs(struct ListNode* head) {
struct ListNode dummyHead;
dummyHead.next = head;
struct ListNode* temp = &dummyHead;
while (temp->next != NULL && temp->next->next != NULL) {
struct ListNode* node1 = temp->next;
struct ListNode* node2 = temp->next->next;
temp->next = node2;
node1->next = node2->next;
node2->next = node1;
temp = node1;
}
return dummyHead.next;
}
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* temp = dummyHead;
while (temp->next != nullptr && temp->next->next != nullptr) {
ListNode* node1 = temp->next;
ListNode* node2 = temp->next->next;
temp->next = node2;
node1->next = node2->next;
node2->next = node1;
temp = node1;
}
return dummyHead->next;
}
};
206. 反转链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mTv5SyrN-1631410080346)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905201236408.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rvlqsjR9-1631410080346)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905201720326.png)]
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* prev = NULL;
struct ListNode* curr = head;
while (curr) {
struct ListNode* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
------------------------------------------------------
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr) {
ListNode* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w8vpEfaa-1631410080347)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905201850306.png)]
struct ListNode* reverseList(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return newHead;
}
-------------------------------------------------------------------------
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head || !head->next) {
return head;
}
ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
}
};
141. 环形链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1jKSUI1k-1631410080347)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905203203031.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A28wIaka-1631410080347)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905203423441.png)]
struct hashTable {
struct ListNode* key;
UT_hash_handle hh;
};
struct hashTable* hashtable;
struct hashTable* find(struct ListNode* ikey) {
struct hashTable* tmp;
HASH_FIND_PTR(hashtable, &ikey, tmp);
return tmp;
}
void insert(struct ListNode* ikey) {
struct hashTable* tmp = malloc(sizeof(struct hashTable));
tmp->key = ikey;
HASH_ADD_PTR(hashtable, key, tmp);
}
bool hasCycle(struct ListNode* head) {
hashtable = NULL;
while (head != NULL) {
if (find(head) != NULL) {
return true;
}
insert(head);
head = head->next;
}
return false;
}
---------------------------------------------------------------
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
unordered_set<ListNode*> seen;
while (head != nullptr) {
if (seen.count(head)) {
return true;
}
seen.insert(head);
head = head->next;
}
return false;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RW6Db3Jn-1631410080348)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905203518134.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cwgke1vk-1631410080348)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905203615964.png)]
bool hasCycle(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return false;
}
struct ListNode* slow = head;
struct ListNode* fast = head->next;
while (slow != fast) {
if (fast == NULL || fast->next == NULL) {
return false;
}
slow = slow->next;
fast = fast->next->next;
}
return true;
}
--------------------------------------------------------------------------
class Solution {
public:
bool hasCycle(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return false;
}
ListNode* slow = head;
ListNode* fast = head->next;
while (slow != fast) {
if (fast == nullptr || fast->next == nullptr) {
return false;
}
slow = slow->next;
fast = fast->next->next;
}
return true;
}
};
剑指 Offer 22. 链表中倒数第k个节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GO2cHsqJ-1631410080349)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905203757623.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vzqVUaW3-1631410080349)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905203823175.png)]
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
int n = 0;
ListNode* node = nullptr;
for (node = head; node; node = node->next) {
n++;
}
for (node = head; n > k; n--) {
node = node->next;
}
return node;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OKcNKbgb-1631410080350)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905203919520.png)]
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode* fast = head;
ListNode* slow = head;
while (fast && k > 0) {
fast = fast->next;
k--;
}
while (fast) {
fast = fast->next;
slow = slow->next;
}
return slow;
}
};
25. K 个一组翻转链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hOy2NZ6V-1631410080350)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905204059546.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V7LiIt70-1631410080350)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905204119590.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zk9UL32c-1631410080351)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905204246343.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DIcgj47J-1631410080351)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905204303965.png)]
/**
* 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:
// 翻转一个子链表,并且返回新的头与尾
pair<ListNode*, ListNode*> myReverse(ListNode* head, ListNode* tail) {
ListNode* prev = tail->next;
ListNode* p = head;
while (prev != tail) {
ListNode* nex = p->next;
p->next = prev;
prev = p;
p = nex;
}
return {tail, head};
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* hair = new ListNode(0);
hair->next = head;
ListNode* pre = hair;
while (head) {
ListNode* tail = pre;
// 查看剩余部分长度是否大于等于 k
for (int i = 0; i < k; ++i) {
tail = tail->next;
if (!tail) {
return hair->next;
}
}
ListNode* nex = tail->next;
// 这里是 C++17 的写法,也可以写成
// pair<ListNode*, ListNode*> result = myReverse(head, tail);
// head = result.first;
// tail = result.second;
tie(head, tail) = myReverse(head, tail);
// 把子链表重新接回原链表
pre->next = head;
tail->next = nex;
pre = tail;
head = tail->next;
}
return hair->next;
}
};
23. 合并K个升序链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lLFJHMBH-1631410080352)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905204424400.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PZ4tUpPv-1631410080352)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905204721839.png)]
ListNode* mergeTwoLists(ListNode *a, ListNode *b) {
if ((!a) || (!b)) return a ? a : b;
ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
while (aPtr && bPtr) {
if (aPtr->val < bPtr->val) {
tail->next = aPtr; aPtr = aPtr->next;
} else {
tail->next = bPtr; bPtr = bPtr->next;
}
tail = tail->next;
}
tail->next = (aPtr ? aPtr : bPtr);
return head.next;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a7u1ODtd-1631410080352)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905204816853.png)]
/**
* 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* mergeTwoLists(ListNode *a, ListNode *b) {
if ((!a) || (!b)) return a ? a : b;
ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
while (aPtr && bPtr) {
if (aPtr->val < bPtr->val) {
tail->next = aPtr; aPtr = aPtr->next;
} else {
tail->next = bPtr; bPtr = bPtr->next;
}
tail = tail->next;
}
tail->next = (aPtr ? aPtr : bPtr);
return head.next;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode *ans = nullptr;
for (size_t i = 0; i < lists.size(); ++i) {
ans = mergeTwoLists(ans, lists[i]);
}
return ans;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fh055srO-1631410080353)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905204858264.png)]
class Solution {
public:
ListNode* mergeTwoLists(ListNode *a, ListNode *b) {
if ((!a) || (!b)) return a ? a : b;
ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
while (aPtr && bPtr) {
if (aPtr->val < bPtr->val) {
tail->next = aPtr; aPtr = aPtr->next;
} else {
tail->next = bPtr; bPtr = bPtr->next;
}
tail = tail->next;
}
tail->next = (aPtr ? aPtr : bPtr);
return head.next;
}
ListNode* merge(vector <ListNode*> &lists, int l, int r) {
if (l == r) return lists[l];
if (l > r) return nullptr;
int mid = (l + r) >> 1;
return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
return merge(lists, 0, lists.size() - 1);
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uH7WtZxs-1631410080353)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905205010709.png)]
class Solution {
public:
struct Status {
int val;
ListNode *ptr;
bool operator < (const Status &rhs) const {
return val > rhs.val;
}
};
priority_queue <Status> q;
ListNode* mergeKLists(vector<ListNode*>& lists) {
for (auto node: lists) {
if (node) q.push({node->val, node});
}
ListNode head, *tail = &head;
while (!q.empty()) {
auto f = q.top(); q.pop();
tail->next = f.ptr;
tail = tail->next;
if (f.ptr->next) q.push({f.ptr->next->val, f.ptr->next});
}
return head.next;
}
};
剑指 Offer 06. 从尾到头打印链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hd9K4VbA-1631410080353)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905205117053.png)]
1.回溯法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void method(vector<int>& res,ListNode* head){
if(head==NULL) return;
method(res,head->next);
res.push_back(head->val);
}
vector<int> reversePrint(ListNode* head) {
vector<int> res;
method(res,head);
return res;
}
};
2.用栈
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
stack<int> s;
vector<int> res;
ListNode* pre=head;
while(pre){
s.push(pre->val);
pre=pre->next;
}
while(!s.empty()){
res.push_back(s.top());
s.pop();
}
return res;
}
};
3.利用vector的insert特性
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> res;
ListNode* pre=head;
while(pre){
res.insert(res.begin(),pre->val);
pre=pre->next;
}
return res;
}
};
92. 反转链表 II
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wn9vVvCa-1631410080354)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905210440394.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ut1kK6BS-1631410080354)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905211255527.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cnMUp0kG-1631410080354)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905211313238.png)]
void reverseLinkedList(struct ListNode *head) {
// 也可以使用递归反转一个链表
struct ListNode *pre = NULL;
struct ListNode *cur = head;
while (cur != NULL) {
struct ListNode *next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
}
struct ListNode *reverseBetween(struct ListNode *head, int left, int right) {
// 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
struct ListNode *dummyNode = malloc(sizeof(struct ListNode));
dummyNode->val = -1;
dummyNode->next = head;
struct ListNode *pre = dummyNode;
// 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
// 建议写在 for 循环里,语义清晰
for (int i = 0; i < left - 1; i++) {
pre = pre->next;
}
// 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
struct ListNode *rightNode = pre;
for (int i = 0; i < right - left + 1; i++) {
rightNode = rightNode->next;
}
// 第 3 步:切断出一个子链表(截取链表)
struct ListNode *leftNode = pre->next;
struct ListNode *curr = rightNode->next;
// 注意:切断链接
pre->next = NULL;
rightNode->next = NULL;
// 第 4 步:同第 206 题,反转链表的子区间
reverseLinkedList(leftNode);
// 第 5 步:接回到原来的链表中
pre->next = rightNode;
leftNode->next = curr;
return dummyNode->next;
}
--------------------------------------------------------
/**
* 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 {
private:
void reverseLinkedList(ListNode *head) {
// 也可以使用递归反转一个链表
ListNode *pre = nullptr;
ListNode *cur = head;
while (cur != nullptr) {
ListNode *next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
}
public:
ListNode *reverseBetween(ListNode *head, int left, int right) {
// 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
ListNode *dummyNode = new ListNode(-1);
dummyNode->next = head;
ListNode *pre = dummyNode;
// 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
// 建议写在 for 循环里,语义清晰
for (int i = 0; i < left - 1; i++) {
pre = pre->next;
}
// 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
ListNode *rightNode = pre;
for (int i = 0; i < right - left + 1; i++) {
rightNode = rightNode->next;
}
// 第 3 步:切断出一个子链表(截取链表)
ListNode *leftNode = pre->next;
ListNode *curr = rightNode->next;
// 注意:切断链接
pre->next = nullptr;
rightNode->next = nullptr;
// 第 4 步:同第 206 题,反转链表的子区间
reverseLinkedList(leftNode);
// 第 5 步:接回到原来的链表中
pre->next = rightNode;
leftNode->next = curr;
return dummyNode->next;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WEaxJrfW-1631410080355)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905211444495.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SDaq757O-1631410080355)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905211508445.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3arbBwKD-1631410080356)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905211530179.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UNtAApBS-1631410080356)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905211545955.png)]
struct ListNode *reverseBetween(struct ListNode *head, int left, int right) {
// 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
struct ListNode *dummyNode = malloc(sizeof(struct ListNode));
dummyNode->val = -1;
dummyNode->next = head;
struct ListNode *pre = dummyNode;
for (int i = 0; i < left - 1; i++) {
pre = pre->next;
}
struct ListNode *cur = pre->next;
struct ListNode *next;
for (int i = 0; i < right - left; i++) {
next = cur->next;
cur->next = next->next;
next->next = pre->next;
pre->next = next;
}
return dummyNode->next;
}
class Solution {
public:
ListNode *reverseBetween(ListNode *head, int left, int right) {
// 设置 dummyNode 是这一类问题的一般做法
ListNode *dummyNode = new ListNode(-1);
dummyNode->next = head;
ListNode *pre = dummyNode;
for (int i = 0; i < left - 1; i++) {
pre = pre->next;
}
ListNode *cur = pre->next;
ListNode *next;
for (int i = 0; i < right - left; i++) {
next = cur->next;
cur->next = next->next;
next->next = pre->next;
pre->next = next;
}
return dummyNode->next;
}
};
61. 旋转链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1MDJiQzg-1631410080357)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905211820557.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fZJHOkWS-1631410080357)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905212013766.png)]
struct ListNode* rotateRight(struct ListNode* head, int k) {
if (k == 0 || head == NULL || head->next == NULL) {
return head;
}
int n = 1;
struct ListNode* iter = head;
while (iter->next != NULL) {
iter = iter->next;
n++;
}
int add = n - k % n;
if (add == n) {
return head;
}
iter->next = head;
while (add--) {
iter = iter->next;
}
struct ListNode* ret = iter->next;
iter->next = NULL;
return ret;
}
--------------------------------------
/**
* 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* rotateRight(ListNode* head, int k) {
if (k == 0 || head == nullptr || head->next == nullptr) {
return head;
}
int n = 1;
ListNode* iter = head;
while (iter->next != nullptr) {
iter = iter->next;
n++;
}
int add = n - k % n;
if (add == n) {
return head;
}
iter->next = head;
while (add--) {
iter = iter->next;
}
ListNode* ret = iter->next;
iter->next = nullptr;
return ret;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KqnTy2mK-1631410080358)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905212057168.png)]
234. 回文链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fBOhQ0IO-1631410080358)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905212221447.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B6gUA4tx-1631410080358)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905212515583.png)]
bool isPalindrome(struct ListNode* head) {
int vals[50001], vals_num = 0;
while (head != NULL) {
vals[vals_num++] = head->val;
head = head->next;
}
for (int i = 0, j = vals_num - 1; i < j; ++i, --j) {
if (vals[i] != vals[j]) {
return false;
}
}
return true;
}
------------------------------------------
/**
* 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:
bool isPalindrome(ListNode* head) {
vector<int> vals;
while (head != nullptr) {
vals.emplace_back(head->val);
head = head->next;
}
for (int i = 0, j = (int)vals.size() - 1; i < j; ++i, --j) {
if (vals[i] != vals[j]) {
return false;
}
}
return true;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YAoUbP9i-1631410080359)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905212646870.png)]
struct ListNode* frontPointer;
bool recursivelyCheck(struct ListNode* currentNode) {
if (currentNode != NULL) {
if (!recursivelyCheck(currentNode->next)) {
return false;
}
if (currentNode->val != frontPointer->val) {
return false;
}
frontPointer = frontPointer->next;
}
return true;
}
bool isPalindrome(struct ListNode* head) {
frontPointer = head;
return recursivelyCheck(head);
}
---------------------------------------------------------------------
class Solution {
ListNode* frontPointer;
public:
bool recursivelyCheck(ListNode* currentNode) {
if (currentNode != nullptr) {
if (!recursivelyCheck(currentNode->next)) {
return false;
}
if (currentNode->val != frontPointer->val) {
return false;
}
frontPointer = frontPointer->next;
}
return true;
}
bool isPalindrome(ListNode* head) {
frontPointer = head;
return recursivelyCheck(head);
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AKxY3gJ0-1631410080359)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905212745050.png)]
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* prev = NULL;
struct ListNode* curr = head;
while (curr != NULL) {
struct ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
struct ListNode* endOfFirstHalf(struct ListNode* head) {
struct ListNode* fast = head;
struct ListNode* slow = head;
while (fast->next != NULL && fast->next->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
bool isPalindrome(struct ListNode* head) {
if (head == NULL) {
return true;
}
// 找到前半部分链表的尾节点并反转后半部分链表
struct ListNode* firstHalfEnd = endOfFirstHalf(head);
struct ListNode* secondHalfStart = reverseList(firstHalfEnd->next);
// 判断是否回文
struct ListNode* p1 = head;
struct ListNode* p2 = secondHalfStart;
bool result = true;
while (result && p2 != NULL) {
if (p1->val != p2->val) {
result = false;
}
p1 = p1->next;
p2 = p2->next;
}
// 还原链表并返回结果
firstHalfEnd->next = reverseList(secondHalfStart);
return result;
}
------------------------------------------------------------------------
class Solution {
public:
bool isPalindrome(ListNode* head) {
if (head == nullptr) {
return true;
}
// 找到前半部分链表的尾节点并反转后半部分链表
ListNode* firstHalfEnd = endOfFirstHalf(head);
ListNode* secondHalfStart = reverseList(firstHalfEnd->next);
// 判断是否回文
ListNode* p1 = head;
ListNode* p2 = secondHalfStart;
bool result = true;
while (result && p2 != nullptr) {
if (p1->val != p2->val) {
result = false;
}
p1 = p1->next;
p2 = p2->next;
}
// 还原链表并返回结果
firstHalfEnd->next = reverseList(secondHalfStart);
return result;
}
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr != nullptr) {
ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
ListNode* endOfFirstHalf(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while (fast->next != nullptr && fast->next->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
};
160. 相交链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xvbl8czi-1631410080360)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905213134048.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vCpc6BDH-1631410080360)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905213351830.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Li0YuSSE-1631410080360)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905213633355.png)]
struct HashTable {
struct ListNode *key;
UT_hash_handle hh;
};
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct HashTable *hashTable = NULL;
struct ListNode *temp = headA;
while (temp != NULL) {
struct HashTable *tmp;
HASH_FIND(hh, hashTable, &temp, sizeof(struct HashTable *), tmp);
if (tmp == NULL) {
tmp = malloc(sizeof(struct HashTable));
tmp->key = temp;
HASH_ADD(hh, hashTable, key, sizeof(struct HashTable *), tmp);
}
temp = temp->next;
}
temp = headB;
while (temp != NULL) {
struct HashTable *tmp;
HASH_FIND(hh, hashTable, &temp, sizeof(struct HashTable *), tmp);
if (tmp != NULL) {
return temp;
}
temp = temp->next;
}
return NULL;
}
--------------------------------
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
unordered_set<ListNode *> visited;
ListNode *temp = headA;
while (temp != nullptr) {
visited.insert(temp);
temp = temp->next;
}
temp = headB;
while (temp != nullptr) {
if (visited.count(temp)) {
return temp;
}
temp = temp->next;
}
return nullptr;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z8gBn4pp-1631410080361)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905213722810.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y0BoXnus-1631410080361)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905213822531.png)]
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if (headA == NULL || headB == NULL) {
return NULL;
}
struct ListNode *pA = headA, *pB = headB;
while (pA != pB) {
pA = pA == NULL ? headB : pA->next;
pB = pB == NULL ? headA : pB->next;
}
return pA;
}
-----------------------------------------------------------------------
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
ListNode *pA = headA, *pB = headB;
while (pA != pB) {
pA = pA == nullptr ? headB : pA->next;
pB = pB == nullptr ? headA : pB->next;
}
return pA;
}
};
83. 删除排序链表中的重复元素
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7GFtl3oM-1631410080362)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905214011846.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wt1bI68X-1631410080362)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905214657236.png)]
struct ListNode* deleteDuplicates(struct ListNode* head) {
if (!head) {
return head;
}
struct ListNode* cur = head;
while (cur->next) {
if (cur->val == cur->next->val) {
cur->next = cur->next->next;
} else {
cur = cur->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* deleteDuplicates(ListNode* head) {
if (!head) {
return head;
}
ListNode* cur = head;
while (cur->next) {
if (cur->val == cur->next->val) {
cur->next = cur->next->next;
}
else {
cur = cur->next;
}
}
return head;
}
};
142. 环形链表 II
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7bumJ9v9-1631410080362)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905214842382.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2doYWEj5-1631410080363)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905214936206.png)]
struct hashTable {
struct ListNode* key;
UT_hash_handle hh;
};
struct hashTable* hashtable;
struct hashTable* find(struct ListNode* ikey) {
struct hashTable* tmp;
HASH_FIND_PTR(hashtable, &ikey, tmp);
return tmp;
}
void insert(struct ListNode* ikey) {
struct hashTable* tmp = malloc(sizeof(struct hashTable));
tmp->key = ikey;
HASH_ADD_PTR(hashtable, key, tmp);
}
struct ListNode* detectCycle(struct ListNode* head) {
hashtable = NULL;
while (head != NULL) {
if (find(head) != NULL) {
return head;
}
insert(head);
head = head->next;
}
return false;
}
-------------------------------------------------------------------------
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
unordered_set<ListNode *> visited;
while (head != nullptr) {
if (visited.count(head)) {
return head;
}
visited.insert(head);
head = head->next;
}
return nullptr;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KOkckEgJ-1631410080363)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905215042765.png)]
struct ListNode* detectCycle(struct ListNode* head) {
struct ListNode *slow = head, *fast = head;
while (fast != NULL) {
slow = slow->next;
if (fast->next == NULL) {
return NULL;
}
fast = fast->next->next;
if (fast == slow) {
struct ListNode* ptr = head;
while (ptr != slow) {
ptr = ptr->next;
slow = slow->next;
}
return ptr;
}
}
return NULL;
}
-----------------------------------------------------------------
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *slow = head, *fast = head;
while (fast != nullptr) {
slow = slow->next;
if (fast->next == nullptr) {
return nullptr;
}
fast = fast->next->next;
if (fast == slow) {
ListNode *ptr = head;
while (ptr != slow) {
ptr = ptr->next;
slow = slow->next;
}
return ptr;
}
}
return nullptr;
}
};
203. 移除链表元素
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aqr6PzA6-1631410080363)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905215232809.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wYzDp9gv-1631410080364)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905215311729.png)]
struct ListNode* removeElements(struct ListNode* head, int val) {
if (head == NULL) {
return head;
}
head->next = removeElements(head->next, val);
return head->val == val ? head->next : head;
}
-------------------------------------------------------------------
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if (head == nullptr) {
return head;
}
head->next = removeElements(head->next, val);
return head->val == val ? head->next : head;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b4UtUNjo-1631410080364)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905215353329.png)]
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode* dummyHead = malloc(sizeof(struct ListNode));
dummyHead->next = head;
struct ListNode* temp = dummyHead;
while (temp->next != NULL) {
if (temp->next->val == val) {
temp->next = temp->next->next;
} else {
temp = temp->next;
}
}
return dummyHead->next;
}
-------------------------------------------------------------------
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
struct ListNode* dummyHead = new ListNode(0, head);
struct ListNode* temp = dummyHead;
while (temp->next != NULL) {
if (temp->next->val == val) {
temp->next = temp->next->next;
} else {
temp = temp->next;
}
}
return dummyHead->next;
}
};
876. 链表的中间结点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ngcFhjOy-1631410080364)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905215711929.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-swf7Le34-1631410080365)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905215740776.png)]
class Solution {
public:
ListNode* middleNode(ListNode* head) {
vector<ListNode*> A = {head};
while (A.back()->next != NULL)
A.push_back(A.back()->next);
return A[A.size() / 2];
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZUeHkQy5-1631410080365)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905215837596.png)]
class Solution {
public:
ListNode* middleNode(ListNode* head) {
int n = 0;
ListNode* cur = head;
while (cur != nullptr) {
++n;
cur = cur->next;
}
int k = 0;
cur = head;
while (k < n / 2) {
++k;
cur = cur->next;
}
return cur;
}
};
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
};
剑指 Offer 18. 删除链表的节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8tjPtYIl-1631410080366)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905220148191.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OlC1Y5po-1631410080366)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905220233558.png)]
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
if(head->val == val) return head->next;
ListNode *pre = head, *cur = head->next;
while(cur != nullptr && cur->val != val) {
pre = cur;
cur = cur->next;
}
if(cur != nullptr) pre->next = cur->next;
return head;
}
};
146. LRU 缓存机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eoghj1QZ-1631410080366)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905220533676.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-STJT1wIh-1631410080367)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905220633471.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B44KzTFr-1631410080367)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905220648376.png)]
struct DLinkedNode {
int key, value;
DLinkedNode* prev;
DLinkedNode* next;
DLinkedNode(): key(0), value(0), prev(nullptr), next(nullptr) {}
DLinkedNode(int _key, int _value): key(_key), value(_value), prev(nullptr), next(nullptr) {}
};
class LRUCache {
private:
unordered_map<int, DLinkedNode*> cache;
DLinkedNode* head;
DLinkedNode* tail;
int size;
int capacity;
public:
LRUCache(int _capacity): capacity(_capacity), size(0) {
// 使用伪头部和伪尾部节点
head = new DLinkedNode();
tail = new DLinkedNode();
head->next = tail;
tail->prev = head;
}
int get(int key) {
if (!cache.count(key)) {
return -1;
}
// 如果 key 存在,先通过哈希表定位,再移到头部
DLinkedNode* node = cache[key];
moveToHead(node);
return node->value;
}
void put(int key, int value) {
if (!cache.count(key)) {
// 如果 key 不存在,创建一个新的节点
DLinkedNode* node = new DLinkedNode(key, value);
// 添加进哈希表
cache[key] = node;
// 添加至双向链表的头部
addToHead(node);
++size;
if (size > capacity) {
// 如果超出容量,删除双向链表的尾部节点
DLinkedNode* removed = removeTail();
// 删除哈希表中对应的项
cache.erase(removed->key);
// 防止内存泄漏
delete removed;
--size;
}
}
else {
// 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
DLinkedNode* node = cache[key];
node->value = value;
moveToHead(node);
}
}
void addToHead(DLinkedNode* node) {
node->prev = head;
node->next = head->next;
head->next->prev = node;
head->next = node;
}
void removeNode(DLinkedNode* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
void moveToHead(DLinkedNode* node) {
removeNode(node);
addToHead(node);
}
DLinkedNode* removeTail() {
DLinkedNode* node = tail->prev;
removeNode(node);
return node;
}
};
148. 排序链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZMaeKkmN-1631410080368)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905220824106.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pR37Ozjq-1631410080368)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905221009502.png)]
struct ListNode* merge(struct ListNode* head1, struct ListNode* head2) {
struct ListNode* dummyHead = malloc(sizeof(struct ListNode));
dummyHead->val = 0;
struct ListNode *temp = dummyHead, *temp1 = head1, *temp2 = head2;
while (temp1 != NULL && temp2 != NULL) {
if (temp1->val <= temp2->val) {
temp->next = temp1;
temp1 = temp1->next;
} else {
temp->next = temp2;
temp2 = temp2->next;
}
temp = temp->next;
}
if (temp1 != NULL) {
temp->next = temp1;
} else if (temp2 != NULL) {
temp->next = temp2;
}
return dummyHead->next;
}
struct ListNode* toSortList(struct ListNode* head, struct ListNode* tail) {
if (head == NULL) {
return head;
}
if (head->next == tail) {
head->next = NULL;
return head;
}
struct ListNode *slow = head, *fast = head;
while (fast != tail) {
slow = slow->next;
fast = fast->next;
if (fast != tail) {
fast = fast->next;
}
}
struct ListNode* mid = slow;
return merge(toSortList(head, mid), toSortList(mid, tail));
}
struct ListNode* sortList(struct ListNode* head) {
return toSortList(head, NULL);
}
----------------------------------------------------------------------
class Solution {
public:
ListNode* sortList(ListNode* head) {
return sortList(head, nullptr);
}
ListNode* sortList(ListNode* head, ListNode* tail) {
if (head == nullptr) {
return head;
}
if (head->next == tail) {
head->next = nullptr;
return head;
}
ListNode* slow = head, *fast = head;
while (fast != tail) {
slow = slow->next;
fast = fast->next;
if (fast != tail) {
fast = fast->next;
}
}
ListNode* mid = slow;
return merge(sortList(head, mid), sortList(mid, tail));
}
ListNode* merge(ListNode* head1, ListNode* head2) {
ListNode* dummyHead = new ListNode(0);
ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;
while (temp1 != nullptr && temp2 != nullptr) {
if (temp1->val <= temp2->val) {
temp->next = temp1;
temp1 = temp1->next;
} else {
temp->next = temp2;
temp2 = temp2->next;
}
temp = temp->next;
}
if (temp1 != nullptr) {
temp->next = temp1;
} else if (temp2 != nullptr) {
temp->next = temp2;
}
return dummyHead->next;
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oFzyzA8e-1631410080368)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905221104244.png)]
struct ListNode* merge(struct ListNode* head1, struct ListNode* head2) {
struct ListNode* dummyHead = malloc(sizeof(struct ListNode));
dummyHead->val = 0;
struct ListNode *temp = dummyHead, *temp1 = head1, *temp2 = head2;
while (temp1 != NULL && temp2 != NULL) {
if (temp1->val <= temp2->val) {
temp->next = temp1;
temp1 = temp1->next;
} else {
temp->next = temp2;
temp2 = temp2->next;
}
temp = temp->next;
}
if (temp1 != NULL) {
temp->next = temp1;
} else if (temp2 != NULL) {
temp->next = temp2;
}
return dummyHead->next;
}
struct ListNode* sortList(struct ListNode* head) {
if (head == NULL) {
return head;
}
int length = 0;
struct ListNode* node = head;
while (node != NULL) {
length++;
node = node->next;
}
struct ListNode* dummyHead = malloc(sizeof(struct ListNode));
dummyHead->next = head;
for (int subLength = 1; subLength < length; subLength <<= 1) {
struct ListNode *prev = dummyHead, *curr = dummyHead->next;
while (curr != NULL) {
struct ListNode* head1 = curr;
for (int i = 1; i < subLength && curr->next != NULL; i++) {
curr = curr->next;
}
struct ListNode* head2 = curr->next;
curr->next = NULL;
curr = head2;
for (int i = 1; i < subLength && curr != NULL && curr->next != NULL;
i++) {
curr = curr->next;
}
struct ListNode* next = NULL;
if (curr != NULL) {
next = curr->next;
curr->next = NULL;
}
struct ListNode* merged = merge(head1, head2);
prev->next = merged;
while (prev->next != NULL) {
prev = prev->next;
}
curr = next;
}
}
return dummyHead->next;
}
---------------------------------------------------------------------
class Solution {
public:
ListNode* sortList(ListNode* head) {
if (head == nullptr) {
return head;
}
int length = 0;
ListNode* node = head;
while (node != nullptr) {
length++;
node = node->next;
}
ListNode* dummyHead = new ListNode(0, head);
for (int subLength = 1; subLength < length; subLength <<= 1) {
ListNode* prev = dummyHead, *curr = dummyHead->next;
while (curr != nullptr) {
ListNode* head1 = curr;
for (int i = 1; i < subLength && curr->next != nullptr; i++) {
curr = curr->next;
}
ListNode* head2 = curr->next;
curr->next = nullptr;
curr = head2;
for (int i = 1; i < subLength && curr != nullptr && curr->next != nullptr; i++) {
curr = curr->next;
}
ListNode* next = nullptr;
if (curr != nullptr) {
next = curr->next;
curr->next = nullptr;
}
ListNode* merged = merge(head1, head2);
prev->next = merged;
while (prev->next != nullptr) {
prev = prev->next;
}
curr = next;
}
}
return dummyHead->next;
}
ListNode* merge(ListNode* head1, ListNode* head2) {
ListNode* dummyHead = new ListNode(0);
ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;
while (temp1 != nullptr && temp2 != nullptr) {
if (temp1->val <= temp2->val) {
temp->next = temp1;
temp1 = temp1->next;
} else {
temp->next = temp2;
temp2 = temp2->next;
}
temp = temp->next;
}
if (temp1 != nullptr) {
temp->next = temp1;
} else if (temp2 != nullptr) {
temp->next = temp2;
}
return dummyHead->next;
}
};
86. 分隔链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YFLzyxlE-1631410080369)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905221416814.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XF3sK1PA-1631410080369)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905221532553.png)]
struct ListNode* partition(struct ListNode* head, int x) {
struct ListNode* small = malloc(sizeof(struct ListNode));
struct ListNode* smallHead = small;
struct ListNode* large = malloc(sizeof(struct ListNode));
struct ListNode* largeHead = large;
while (head != NULL) {
if (head->val < x) {
small->next = head;
small = small->next;
} else {
large->next = head;
large = large->next;
}
head = head->next;
}
large->next = NULL;
small->next = largeHead->next;
return smallHead->next;
}
----------------------------------------------------------------------
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode* small = new ListNode(0);
ListNode* smallHead = small;
ListNode* large = new ListNode(0);
ListNode* largeHead = large;
while (head != nullptr) {
if (head->val < x) {
small->next = head;
small = small->next;
} else {
large->next = head;
large = large->next;
}
head = head->next;
}
large->next = nullptr;
small->next = largeHead->next;
return smallHead->next;
}
};
328. 奇偶链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QGygy2oM-1631410080369)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905221708635.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H6FMnTjW-1631410080370)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905221737897.png)]
struct ListNode* oddEvenList(struct ListNode* head) {
if (head == NULL) {
return head;
}
struct ListNode* evenHead = head->next;
struct ListNode* odd = head;
struct ListNode* even = evenHead;
while (even != NULL && even->next != NULL) {
odd->next = even->next;
odd = odd->next;
even->next = odd->next;
even = even->next;
}
odd->next = evenHead;
return head;
}
-----------------------------------------------------------------------
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
if (head == nullptr) {
return head;
}
ListNode* evenHead = head->next;
ListNode* odd = head;
ListNode* even = evenHead;
while (even != nullptr && even->next != nullptr) {
odd->next = even->next;
odd = odd->next;
even->next = odd->next;
even = even->next;
}
odd->next = evenHead;
return head;
}
};
138. 复制带随机指针的链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w650oxlZ-1631410080371)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905221950589.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9qth5A1G-1631410080371)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905222004214.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TBUxoVfz-1631410080371)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905222040588.png)]
struct HashTable {
struct Node *key, *val;
UT_hash_handle hh;
} * cachedNode;
struct Node* deepCopy(struct Node* head) {
if (head == NULL) {
return NULL;
}
struct HashTable* tmp;
HASH_FIND_PTR(cachedNode, &head, tmp);
if (tmp == NULL) {
struct Node* headNew = malloc(sizeof(struct Node));
headNew->val = head->val;
tmp = malloc(sizeof(struct HashTable));
tmp->key = head, tmp->val = headNew;
HASH_ADD_PTR(cachedNode, key, tmp);
headNew->next = deepCopy(head->next);
headNew->random = deepCopy(head->random);
}
return tmp->val;
}
struct Node* copyRandomList(struct Node* head) {
cachedNode = NULL;
return deepCopy(head);
}
------------------------------------------------------------------
class Solution {
public:
unordered_map<Node*, Node*> cachedNode;
Node* copyRandomList(Node* head) {
if (head == nullptr) {
return nullptr;
}
if (!cachedNode.count(head)) {
Node* headNew = new Node(head->val);
cachedNode[head] = headNew;
headNew->next = copyRandomList(head->next);
headNew->random = copyRandomList(head->random);
}
return cachedNode[head];
}
};
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NlDWEL6L-1631410080372)(https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210905222140621.png)]
struct Node* copyRandomList(struct Node* head) {
if (head == NULL) {
return NULL;
}
for (struct Node* node = head; node != NULL; node = node->next->next) {
struct Node* nodeNew = malloc(sizeof(struct Node));
nodeNew->val = node->val;
nodeNew->next = node->next;
node->next = nodeNew;
}
for (struct Node* node = head; node != NULL; node = node->next->next) {
struct Node* nodeNew = node->next;
nodeNew->random = (node->random != NULL) ? node->random->next : NULL;
}
struct Node* headNew = head->next;
for (struct Node* node = head; node != NULL; node = node->next) {
struct Node* nodeNew = node->next;
node->next = node->next->next;
nodeNew->next = (nodeNew->next != NULL) ? nodeNew->next->next : NULL;
}
return headNew;
}
-----------------------------------------------------------------------
class Solution {
public:
Node* copyRandomList(Node* head) {
if (head == nullptr) {
return nullptr;
}
for (Node* node = head; node != nullptr; node = node->next->next) {
Node* nodeNew = new Node(node->val);
nodeNew->next = node->next;
node->next = nodeNew;
}
for (Node* node = head; node != nullptr; node = node->next->next) {
Node* nodeNew = node->next;
nodeNew->random = (node->random != nullptr) ? node->random->next : nullptr;
}
Node* headNew = head->next;
for (Node* node = head; node != nullptr; node = node->next) {
Node* nodeNew = node->next;
node->next = node->next->next;
nodeNew->next = (nodeNew->next != nullptr) ? nodeNew->next->next : nullptr;
}
return headNew;
}
};