目录
链表遍历
相交链表
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (!headA || !headB)
return nullptr;
ListNode *pA = headA, *pB = headB;
while (pA != pB) {
pA = pA == nullptr ? headB : pA->next;
pB = pB == nullptr ? headA : pB->next;
}
return pA;
}
环形链表
链表形成回路(环),快慢指针
// 判断是否成环
bool hasCycle(ListNode* head) {
if (!head || !head->next)
return false;
ListNode* slow = head;
ListNode* fast = head->next;
while (slow != fast) {
if (!fast || !fast->next)
return false;
slow = slow->next;
fast = fast->next->next;
}
return true;
}
// 输出环的入口节点
ListNode *detectCycle(ListNode *head) {
ListNode *slow = head, *fast = head;
while (fast) {
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;
}
重排链表
将原链表重排至头尾头尾的形式,如图:
void reorderList(ListNode* head) {
if (!head) return;
ListNode* mid = middleNode(head);
ListNode* l1 = head;
ListNode* l2 = mid->next;
mid->next = nullptr;
l2 = reverseList(l2);
mergeList(l1, l2);
}
// 获取中点
ListNode* middleNode(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
// 翻转链表
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr) {
ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
// 合并链表
void mergeList(ListNode* l1, ListNode* l2) {
ListNode *l1_tmp, *l2_tmp;
while (l1 && l2) {
l1_tmp = l1->next;
l2_tmp = l2->next;
l1->next = l2;
l1 = l1_tmp;
l2->next = l1;
l2 = l2_tmp;
}
}
链表排序
插入排序
ListNode* insertionSortList(ListNode* head) {
if (!head) return nullptr;
ListNode* dummyHead = new ListNode(0, head);
ListNode* lastSorted = head;
ListNode* curr = head->next;
while (curr) {
if (lastSorted->val <= curr->val)
lastSorted = lastSorted->next;
else {
ListNode *prev = dummyHead;
while (prev->next->val <= curr->val)
prev = prev->next;
lastSorted->next = curr->next;
curr->next = prev->next;
prev->next = curr;
}
curr = lastSorted->next;
}
return dummyHead->next;
}
归并排序
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;
}
递归写法
ListNode* sortList(ListNode* head) {
if (!head || !head->next)
return head;
ListNode* head1 = head;
ListNode* head2 = split(head);
head1 = sortList(head1);
head2 = sortList(head2);
return merge(head1, head2);
}
ListNode* split(ListNode* head) {
ListNode *slow = head, *fast = head->next;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
ListNode* mid = slow->next;
slow->next = nullptr;
return mid;
}
ListNode* merge(ListNode* head1, ListNode* head2) {
ListNode *dummy = new ListNode(0), *p = dummy;
while (head1 && head2) {
if (head1->val < head2->val) {
p = p->next = head1;
head1 = head1->next;
}
else {
p = p->next = head2;
head2 = head2->next;
}
}
if (head1 != nullptr) p->next = head1;
if (head2 != nullptr) p->next = head2;
return dummy->next;
}
链表合并
合并两个有序链表
// 递归
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l1 == nullptr) return l2;
if (l2 == nullptr) return l1;
if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
// 迭代
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;
}
prev->next = l1 == nullptr ? l2 : l1;
return preHead->next;
}
合并n个有序链表
struct node{
ListNode *p;
int val;
bool operator<(const node &a) const {
return a.val < val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<node> Q;
for (auto &x : lists) {
if (x) Q.push({x, x->val});
}
ListNode *head = nullptr, *now = nullptr;
while (!Q.empty()) {
node tmp = Q.top();
Q.pop();
if (!head) head = now = tmp.p;
else {
now->next = tmp.p;
now = tmp.p;
}
if (!tmp.p->next)
continue;
Q.push({tmp.p->next, tmp.p->next->val});
}
return head;
}
链表修改
翻转链表
// 迭代
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;
}
// 递归
ListNode* reverseList(ListNode* head) {
if (!head || !head->next)
return head;
ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
}
翻转k个一组链表
void myReverse(ListNode*&head, ListNode*&tail) {
ListNode* prev = tail->next, *p = head;
while (prev != tail) {
ListNode* nex = p->next;
p->next = prev;
prev = p;
p = nex;
}
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* hair = new ListNode(0), *pre = hair;
hair->next = head;
while (head) {
ListNode* tail = pre;
for (int i = 0; i < k; ++i) {
tail = tail->next;
if (!tail)
return hair->next;
}
ListNode* nex = tail->next;
myReverse(head, tail);
pre->next = tail;
head->next = nex;
pre = head;
head = pre->next;
}
return hair->next;
}
删除链表倒数第k个节点
// 递归
void dfs(ListNode *p, int n, int &x) {
if (p->next)
dfs(p->next, n, x);
++x;
if (x == n+1)
p->next = p->next->next;
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *h = new ListNode(0, head);
int x = 0;
dfs(h, n, x);
return h->next;
}
// 双指针
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;
}
删除链表中重复的元素
重复的元素仅保留一个就好
ListNode* deleteDuplicates(ListNode* head) {
if (!head) return nullptr;
ListNode* cur = head;
while (cur->next) {
if (cur->val == cur->next->val)
cur->next = cur->next->next;
else cur = cur->next;
}
return head;
}
重复的元素都不能保留
ListNode* deleteDuplicates(ListNode* head) {
if (!head) return nullptr;
ListNode *ret = new ListNode(-1, head) *now = ret;
while (now->next && now->next->next) {
if (now->next->val == now->next->next->val) {
int num = now->next->val;
while (now->next && now->next->val == num)
now->next = now->next->next;
}
else now = now->next;
}
return ret->next;
}
两两交换链表中的节点
// 递归
ListNode* swapPairs(ListNode* head) {
if (!head) return nullptr;
if (!head->next) return head;
ListNode *nxt = head->next;
head->next = swapPairs(nxt->next);
nxt->next = head;
return nxt;
}
// 迭代
ListNode* swapPairs(ListNode* head) {
ListNode *ret = new ListNode(-1);
ListNode *p = head, *last = ret;
while (p && p->next) {
ListNode *tmp = p->next;
last->next = tmp;
p->next = tmp->next;
tmp->next = p;
last = p;
p = p->next;
}
if (!ret->next) return head;
return ret->next;
}
旋转链表-整体右移k步
ListNode* rotateRight(ListNode* head, int k) {
if (!k || !head) return head;
ListNode *p = head;
int len = 1;
while (p && p->next) {
p = p->next;
++len;
}
p->next = head;
k %= len;
for (int i = 0; i < len-k-1; ++i) {
head = head->next;
}
p = head->next;
head->next = nullptr;
return p;
}