文章目录
- 链表
- 两数相加
- [237. 删除链表中的节点 - 力扣(LeetCode)](https://leetcode-cn.com/problems/delete-node-in-a-linked-list/)
- 删除链表的倒数第N个节点
- 合并有序链表
- 合并k个升序链表
- 反转链表
- 反转链表II
- 删除元素
- 删除元素II
- [203. 移除链表元素 - 力扣(LeetCode)](https://leetcode-cn.com/problems/remove-linked-list-elements/)
- 两两交换链表节点
- K个一组翻转链表
- 旋转链表
- [138. 复制带随机指针的链表 - 力扣(LeetCode)](https://leetcode-cn.com/problems/copy-list-with-random-pointer/)
- [160. 相交链表 - 力扣(LeetCode)](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/)
- [430. 扁平化多级双向链表 - 力扣(LeetCode)](https://leetcode-cn.com/problems/flatten-a-multilevel-doubly-linked-list/submissions/)
- [725. 分隔链表 - 力扣(LeetCode)](https://leetcode-cn.com/problems/split-linked-list-in-parts/submissions/)
链表
两数相加
添加一个有默认值的参数cnt,递归完成结果
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2, int cnt = 0) {
if(l1 == nullptr && l2 == nullptr)
{
if(cnt == 0) return nullptr;
else return new ListNode(cnt);
}
if(l1 == nullptr) l1 = new ListNode(0);
if(l2 == nullptr) l2 = new ListNode(0);
int sum = l1->val + l2->val + cnt;
ListNode* head = new ListNode(sum % 10);
head->next = addTwoNumbers(l1->next, l2->next, sum / 10);
return head;
}
};
237. 删除链表中的节点 - 力扣(LeetCode)
class Solution {
public:
void deleteNode(ListNode* node) {
if(!node->next)
{
return;
}
else if(!node->next->next)
{
node->val = node->next->val;
node->next = NULL;
}
else
{
node->val = node->next->val;
deleteNode(node->next);
}
}
};
删除链表的倒数第N个节点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* fast = head;
ListNode* low = head;
ListNode* last;
while(n --) fast = fast->next;
if(fast == nullptr) return head->next;
while(fast != nullptr)
{
fast = fast->next;
last = low;
low = low->next;
}
last->next = low->next;
return head;
}
};
合并有序链表
class Solution {
public:
//合并两个链表
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* head = new ListNode();
ListNode* t = head;
while(list1 != nullptr && list2 != nullptr)
{
if(list1->val < list2->val)
{
head->next = list1;
list1 = list1->next;
}
else
{
head->next = list2;
list2 = list2->next;
}
head = head->next;
}
if(list1 != nullptr) head->next = list1;
if(list2 != nullptr) head->next = list2;
return t->next;
}
};
合并k个升序链表
二分合并
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(!lists.size()) return nullptr;
int num1 = 0, num2 = 1;
while(lists.size() - num1 > 1)
{
auto a = lists[num1];
auto b = lists[num2];
num1 += 2;
num2 += 2;
lists.push_back(mergeTwoLists(a, b));
}
return lists[lists.size() - 1];
}
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* head = new ListNode();
ListNode* t = head;
while(list1 != nullptr && list2 != nullptr)
{
if(list1->val < list2->val)
{
head->next = list1;
list1 = list1->next;
}
else
{
head->next = list2;
list2 = list2->next;
}
head = head->next;
}
if(list1 != nullptr) head->next = list1;
if(list2 != nullptr) head->next = list2;
return t->next;
}
};
反转链表
回溯法
函数的意义是返回翻转后的链表头。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == nullptr || head->next == nullptr)
return head;
ListNode *newhead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newhead;
}
};
迭代法
制造一个空的 pre 节点用来存储前一个节点
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head) return head;
ListNode *pre = nullptr;
while(head)
{
ListNode *ne = head->next;
head->next = pre;
pre = head;
head = ne;
}
return pre;
}
};
反转链表II
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode *q = head, *p, *r, *temp_head = nullptr, *temp_tail;//将temp_head初始化为NULL。
for(int i = 1; i < left; i++){
if(i == left - 1)temp_head = q;//找到left的前驱,将temp_head指向它。
q = q->next;
}
temp_tail = q;//temp_tail指向left节点
p = temp_head;//p就位
r = q->next;//r就位
for(int i = left; i < right; i++){//开始翻转
q->next = p;
p = q;
q = r;
r = r->next;
}
q->next = p;//最后一个要翻转的节点在循环里没有涉及到,这里出来了处理一下。
if(temp_head)temp_head->next = q;//只有left不是head节点时才执行。
temp_tail->next = r;
return temp_head ? head : q;//返回值判断一下再返回
}
};
删除元素
回溯法
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(head == nullptr || head->next == nullptr)
return head;
ListNode *p = head;
if(head->val == head->next->val)//如果相等就要删除head的下一个。
{
head->next = head->next->next;
deleteDuplicates(head);
}
else
deleteDuplicates(head->next);//不相等说明head已经是不重复的了,进行下一个。
return p;
}
};
迭代法,与回溯法思路一致
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode *p = head;
while(head&&head->next)
{
if(head->val == head->next->val)
head->next = head->next->next;
else
head = head->next;
}
return p;
}
};
删除元素II
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(head == nullptr || head->next == nullptr)return head;
if(head->val == head->next->val)
{
head = deletenode(head, head->val);//删除当前重复节点并找到新head
head = deleteDuplicates(head);//继续检查新head是否需要删除
}
else
head->next = deleteDuplicates(head->next);//不需要删除head就检查下一个节点并将head连接到新节点
return head;
}
ListNode* deletenode(ListNode* head, int x)
{
while(head && head->val == x)
head = head->next;
return head;
}
};
203. 移除链表元素 - 力扣(LeetCode)
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(head == nullptr) return nullptr;
if(head->val == val)
return removeElements(head->next, val);
head->next = removeElements(head->next, val);
return head;
}
};
两两交换链表节点
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(!head || !head->next)return head;
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* h = new ListNode();
h->next = head->next;
head->next = swapPairs(head->next->next);
h->next->next = head;
return h->next;
}
};
K个一组翻转链表
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* dum = new ListNode();
dum->next = head;
ListNode* cur = dum;
while(cur != nullptr)
{
reverse(cur, k);
int u = k;
while(u-- > 0 && cur != nullptr) cur = cur->next;
};
return dum->next;
}
void reverse(ListNode* root, int k)
{
int u = k;
ListNode* cur = root;
while(u -- > 0 && cur != nullptr) cur = cur->next;
if(cur == nullptr) return;
ListNode* tail = cur->next;
ListNode* a = root->next;
ListNode* b = a->next; //三个指针
//中间有k - 1个指针需要翻转
while(k -- > 1)
{
ListNode* c = b->next;
b->next = a;
a = b;
b = c;
}
root->next->next = tail;
root->next = a;
}
};
旋转链表
class Solution {
public:
//成环再断开
ListNode* rotateRight(ListNode* head, int k) {
if(head == nullptr) return nullptr;
int n = 0;
ListNode* p = head;
while(p->next != nullptr)
{
n ++;
p = p->next;
}
n ++;
k = k % n;
p->next = head;
k = n - k;
while(k -- > 1)
{
head = head->next;
}
p = head->next;
head->next = nullptr;
return p;
}
};
138. 复制带随机指针的链表 - 力扣(LeetCode)
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
Node* h = new Node(0);
Node* h1 = h;
Node* hh = h;
Node* t = head;
Node* t1 = head;
while(t != nullptr)
{
h->next = new Node(t->val);
t = t->next;
h = h->next;
}
while(t1 != nullptr)
{
if(t1->random != nullptr)
{
h1->next->random = find(head, hh -> next, t1->random);
}
t1 = t1->next;
h1 = h1->next;
}
return hh->next;
}
Node* find(Node* h1, Node* h2, Node* t)
{
while(h1 != nullptr)
{
if(h1 == t)
return h2;
h1 = h1->next;
h2 = h2->next;
}
return nullptr;
}
};
160. 相交链表 - 力扣(LeetCode)
/**
* 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) {
ListNode *p1 = headA;
ListNode *p2 = headB;
if(!p1||!p2)return NULL;
while(p1!=p2)
{
if(p1 == NULL)p1 = headB;
else p1 = p1->next;
if(p2 == NULL)p2 = headA;
else p2 = p2->next;
}
return p2;
}
};
430. 扁平化多级双向链表 - 力扣(LeetCode)
class Solution {
public:
Node* flatten(Node* head) {
for (Node* curr = head; curr != nullptr; curr = curr->next){
// 如果遇到 curr->child 需要把一整层移上来
if (curr->child){
// 子链表一整层[start, end]
Node* start = curr->child;
Node* end = start;
while (end->next != nullptr) end = end->next;
// 把一整层带上来 (深度减去一层)
end->next = curr->next;
if (curr->next != nullptr) curr->next->prev = end;
curr->next = start;
start->prev = curr;
curr->child = nullptr;
}
}
return head;
}
};
725. 分隔链表 - 力扣(LeetCode)
/**
* 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:
vector<ListNode*> splitListToParts(ListNode* head, int k) {
ListNode* h = head;
int cnt = 0;
while(h != nullptr)
{
cnt ++;
h = h->next;
}
//cnt = a(b + 1) + (k - a)(b) = ab + a + kb - ab = a + kb
int a, b;
b = cnt / k;
a = cnt - k * b;
vector<ListNode*> ans;
for(int i = 1; i <= k; i ++ )//k组
{
if(i <= a)//a组b+1
{
ans.push_back(head);
for(int j = 1; j <= b; j ++ )
{
head = head->next;
}
ListNode* ne = head->next;
head->next = nullptr;
head = ne;
}
else
{
if(b == 0)
{
ans.push_back(nullptr);
continue;
}
ans.push_back(head);
for(int j = 1; j <= b - 1; j ++ )
{
head = head->next;
}
ListNode* ne = head->next;
head->next = nullptr;
head = ne;
}
}
return ans;
}
};