文章目录
八大排序
插冒归稳定







快排过程
以 [3,4,6,1,2,4,7] 为例,以第一个元素3为base,定义左右两个指针(小熊l,小熊r),分别从两端开始扫描。从右向左找比3小的数,替换l所在位置的元素。再从左往右找比3大的数,然后替换r所在位置的元素。重复此过程直至两个小熊重合(两个指针指向同一元素),base替换此元素,此时第一轮结束。再递归排序base左右两部分的元素。
卡特兰数

C0 = 1,
C1 = 1, C2 = 2, C3 = 5, C4 = 14, C5 = 42,
C6 = 132, C7 = 429, C8 = 1430, C9 = 4862, C10 = 16796,
C11 = 58786, C12 = 208012, C13 = 742900, C14 = 2674440, C15 = 9694845,
C16 = 35357670, C17 = 129644790, C18 = 477638700, C19 = 1767263190, C20 = 6564120420, ...
反转链表
💡 采用翻指针法,将每个节点的next指针翻转一下,让其指向前一个节点即可
struct ListNode* ReverseList(struct ListNode* head )
{
struct ListNode* prev=NULL;//prev指针初始为为NULL,考虑链表本身为空的情况
struct ListNode* cur=head;
while(cur)
{
struct ListNode* next=cur->next;//先保存下一个节点,防止下面翻指针过程中丢失next节点
cur->next=prev;
prev=cur;
cur=next;
}
return prev;//prev最终指向原链表最后一个节点,即翻转后的第一个节点
}
💡 头插法,遍历原链表每个节点,将其头插到初始为NULL的新链表上即可
struct ListNode* ReverseList(struct ListNode* head )
{
struct ListNode* cur=NULL;//cur指针初始化为NULL,考虑链表本身为空的情况
while(head)
{
struct ListNode* next=head->next;//先保存下一个节点,防止下面翻指针过程中丢失next节点
//头插
head->next=cur;
cur=head;
head=next;
}
return cur;//cur最终指向原链表最后一个节点,即翻转后的第一个节点
}
💡 递归法,先递归到最后链表的最后一个节点处,然后在回退的时候进行翻指针
struct ListNode* ReverseList(struct ListNode* head )
{
if(head==NULL||head->next==NULL)
{
return head;
}
struct ListNode* cur = ReverseList(head->next);// 这里的cur就是最后一个节点
head->next->next = head;
// 防止链表循环,需要将head.next设置为空
head->next = NULL;
// 每层递归函数都返回cur,也就是最后一个节点
return cur;//这里就是将最后一个节点不断返回回去
}
💡 三指针法,就是用三个指针定位三个节点,做到翻指针的效果
struct ListNode *ReverseList(struct ListNode *head)
{
if (head == NULL)
{
return NULL;
}
struct ListNode *prv = NULL, *cur = head, *nxt = cur->next;
while (cur)
{
cur->next = prv;
prv = cur;
cur = nxt;
if (nxt)
nxt = nxt->next;
}
return prv;
}
链表的回文结构
- 先通过快慢指针的方式,找到链表中间节点。
- 再将后半部分链表进行反转。
- 最后将链表前半部分和反转后的后半部分链表逐节点进行比较判断。
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
if (A == nullptr || A->next == nullptr)
return true;
ListNode* slow, *fast;
slow = fast = A;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
ListNode* prev, *cur, *nxt;
prev = nullptr;
cur = slow;
while (cur) {
nxt = cur->next;
cur->next = prev;
prev = cur;
cur = nxt;
}
while (A && prev) {
if (A->val != prev->val)
return false;
A = A->next;
prev = prev->next;
}
return true;
}
};
左叶子之和
class Solution {
public:
void _helper(TreeNode* root, int& sum) {
if (root == nullptr)
return;
if (root->left && !root->left->left && !root->left->right)
sum += root->left->val;
_helper(root->left, sum);
_helper(root->right, sum);
}
int sumOfLeftLeaves(TreeNode* root) {
int sum = 0;
_helper(root, sum);
return sum;
}
};
另一棵树的子树
class Solution {
public:
bool isSubtree(TreeNode* s, TreeNode* t) {
if (!s && !t)
return true;
// 代码走到这里 已经保证s t不全空
if (!s || !t)
return false;
return isSameTree(s, t) || isSubtree(s->left, t) ||
isSubtree(s->right, t);
}
bool isSameTree(TreeNode* s, TreeNode* t) {
if (!s && !t)
return true;
if (!s || !t)
return false;
return (s->val == t->val) && isSameTree(s->left, t->left) &&
isSameTree(s->right, t->right);
}
};
归并排序
递归
#include <iostream>
#include <vector>
void merge(std::vector<int>& arr, int left, int mid, int right) {
std::vector<int> leftArr(arr.begin() + left, arr.begin() + mid + 1);
std::vector<int> rightArr(arr.begin() + mid + 1, arr.begin() + right + 1);
int i = 0, j =
2475




被折叠的 条评论
为什么被折叠?



