导航菜单
首页 >  408考研算法题  > 贼全面的计算机考研数据结构算法题集合(408+自命题均可)

贼全面的计算机考研数据结构算法题集合(408+自命题均可)

文章目录Code数组合并排序的数组约瑟夫环问题——高效解法 栈栈实现队列最小栈逆波兰表达式求值 队列设计循环队列 链表删除链表节点删除链表中间节点删除链表的倒数第n个节点删除链表中的重复元素相交链表链表中环的入口点反转链表旋转链表合并两个链表重排链表链表排序——插入链表排序——归并 二叉树中序遍历前序遍历后序遍历二叉树的层序遍历前序 + 中序 构建二叉树有序数组转为二叉搜索树将二叉搜索树变平衡二叉树的最近公共祖先层数最深的叶子节点的和对称二叉树二叉树的右视图 排序插入 冒泡 选择希尔 快排 堆排 归并基数 计数双轴快排按奇偶排序数组——快排荷兰国旗问题——颜色分类——快排数组中的多数元素——快排逆序对问题——归并Top K 问题——堆排最小的 K 个数——堆排最大间距——基排排序杂题相对名次 双指针无重复字符的最长子串 二分旋转数组的最小数字0~n-1 中缺失的数字 深度优先搜索 dfs括号生成路径总和 贪心三元组最小距离 动态规划最大子数组和最大乘积子数组最长公共子序列最长公共子数组(最长重复子数组)最长递增子序列01背包 *完全背包 *零钱兑换——完全背包变体 *零钱兑换II ——完全背包变体 * 杂题回文数字符串压缩——模拟 杂题回文数字符串压缩——模拟

背包问题已经标 *,有一说一,几率应该不大,所以不是重点,可以理解则理解,否则 pass。重要的还是排序、树的遍历,递归,非递归这些。图论算法也的看看,尤其是图的遍历,其实和树的一样,就是需要标记一下访问过的节点,避免死循环。

Code 数组 合并排序的数组

给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。

初始化 A 和 B 的元素数量分别为 m 和 n。

void merge(int* A, int ASize, int m, int* B, int BSize, int n){if(ASize == 0) return;int * c = (int *)malloc(sizeof(int )*ASize);int num = 0,j,k;for(int i = 0;i top_in)] = x;obj->size++;return ;}int myQueuePop(MyQueue* obj) {if(obj->top_out == -1){while(obj->top_in >= 0)obj->out_stack[++(obj->top_out)] = obj->in_stack[(obj->top_in)--];}(obj->size)--;return obj->out_stack[(obj->top_out)--];}int myQueuePeek(MyQueue* obj) {if(obj->top_out == -1){while(obj->top_in >= 0)obj->out_stack[++(obj->top_out)] = obj->in_stack[(obj->top_in)--];}return obj->out_stack[obj->top_out];}bool myQueueEmpty(MyQueue* obj) {if(obj->size == 0)return true;elsereturn false;}void myQueueFree(MyQueue* obj) {free(obj->in_stack);free(obj->out_stack);obj->top_out = -1;obj->top_in = -1;obj->size = 0;return ;}/** * Your MyQueue struct will be instantiated and called as such: * MyQueue* obj = myQueueCreate(); * myQueuePush(obj, x); * int param_2 = myQueuePop(obj); * int param_3 = myQueuePeek(obj); * bool param_4 = myQueueEmpty(obj); * myQueueFree(obj);*/ 最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

push(x) —— 将元素 x 推入栈中。pop() —— 删除栈顶的元素。top() —— 获取栈顶元素。getMin() —— 检索栈中的最小元素。typedef struct {int *arr;int top;int size;//xieshangzaishuoint min_num;int *brr;} MinStack;MinStack* minStackCreate() {MinStack* m = (MinStack *)malloc(sizeof(MinStack)*1);m->arr = (int *)malloc(sizeof(int)*101000);m->brr = (int *)malloc(sizeof(int)*101000);m->top = -1;m->size = 0;m->min_num = 2147483647;return m;}void minStackPush(MinStack* obj, int val) {obj->arr[++(obj->top)] = val;(obj->size)++;if(val min_num)){obj->min_num = val;// obj->brr[(obj->top)] = obj->min_num;}obj->brr[(obj->top)] = obj->min_num;// else// obj->brr[(obj->top)] = }int minStackTop(MinStack* obj) {return obj->arr[(obj->top)];}void minStackPop(MinStack* obj) {(obj->size)-= 1;(obj->top)--;// 最小的弹出去之后 记得更新 min_numif(obj->size == 0)obj->min_num = 2147483647;elseobj->min_num = obj->brr[(obj->top)];}int minStackGetMin(MinStack* obj) {return obj->brr[obj->top];}void minStackFree(MinStack* obj) {free(obj->arr);free(obj->brr);obj->size = 0;obj->top = -1;obj->min_num = 0;} 逆波兰表达式求值

根据 逆波兰表示法,求表达式的值。

有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。/*遇到数字就入栈,遇到符号就将栈顶的两个元素取出进行计算,将计算的结果入栈*/int evalRPN(char ** tokens, int tokensSize){int *stack = (int *)calloc(tokensSize,sizeof(int));int top = 0;int a,b;for(int i = 0;i = 42 && c[0] queue = (int *)calloc(k,sizeof(int));q->k = k;q->front = -1;q->rear = -1;q->length = 0;return q;}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(obj->length == obj->k)return false;if(obj->front == -1 && obj->rear == -1){obj->front = 0;obj->rear = 0;}obj->queue[obj->rear] = value;obj->rear = (obj->rear+1)%obj->k;obj->length++;return true;}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(obj->length == 0)return false;obj->front = (obj->front+1)%obj->k;obj->length--;return true;}int myCircularQueueFront(MyCircularQueue* obj) {if(obj->length == 0)return -1;return obj->queue[obj->front];}int myCircularQueueRear(MyCircularQueue* obj) {if(obj->length == 0)return -1;if(obj->rear - 1 == -1)return obj->queue[obj->rear-1+obj->k];return obj->queue[obj->rear-1];}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {if(obj->length != 0)return false;return true;}bool myCircularQueueIsFull(MyCircularQueue* obj) {if(obj->length != obj->k)return false;return true;}void myCircularQueueFree(MyCircularQueue* obj) {obj->front = -1;obj->rear = -1;obj->length = 0;if(obj->queue != NULL){free(obj->queue);obj->queue = NULL;}if (obj != NULL) {free(obj);obj = NULL;}}/** * Your MyCircularQueue struct will be instantiated and called as such: * MyCircularQueue* obj = myCircularQueueCreate(k); * bool param_1 = myCircularQueueEnQueue(obj, value); * bool param_2 = myCircularQueueDeQueue(obj); * int param_3 = myCircularQueueFront(obj); * int param_4 = myCircularQueueRear(obj); * bool param_5 = myCircularQueueIsEmpty(obj); * bool param_6 = myCircularQueueIsFull(obj); * myCircularQueueFree(obj);*/ 链表 删除链表节点

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

struct ListNode* deleteNode(struct ListNode* head, int val){int num = val;struct ListNode* s = (struct ListNode*)malloc(sizeof(struct ListNode)*1);s->next = head;struct ListNode*p,*q;p = s;while(p->next!=NULL){if(p->next->val == num){q = p->next;p->next = q->next;break;}p = p->next;}return s->next;} 删除链表中间节点

给你一个链表的头节点 head 。删除 链表的 中间节点 ,并返回修改后的链表的头节点 head 。

长度为 n 链表的中间节点是从头数起第 ⌊n / 2⌋ 个节点(下标从 0 开始),其中 ⌊x⌋ 表示小于或等于 x 的最大整数。

对于 n = 1、2、3、4 和 5 的情况,中间节点的下标分别是 0、1、1、2 和 2 。// 一波优雅的快慢指针struct ListNode* deleteMiddle(struct ListNode* head){if(head->next == NULL)return NULL;struct ListNode* l = (struct ListNode*)calloc(1,sizeof(struct ListNode));l->next = head;struct ListNode*p,*q;q = head;p = l;while(q != NULL && q->next != NULL){q = q->next->next;p = p->next;}// q = p->next;p->next = p->next->next;return l->next;} 删除链表的倒数第n个节点 struct ListNode* removeNthFromEnd(struct ListNode* head, int n){struct ListNode *p,*q;struct ListNode *l = (struct ListNode*)malloc(sizeof(struct ListNode)*1);l->next = NULL;l->next = head;p = q = l; //p->next指向第n-1结点 q->next指向后边的结点while(n--){p = p->next;}while(p->next != NULL){p = p->next;q = q->next;}p = q->next;q->next = q->next->next;free(p);return l->next;} 删除链表中的重复元素

存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。

返回同样按升序排列的结果链表。

struct ListNode* deleteDuplicates(struct ListNode* head){if(head == NULL)return NULL;if(head->next == NULL)return head;struct ListNode* s,* p,* pre,* q;struct ListNode* l = (struct ListNode *)malloc(sizeof(struct ListNode)*1);s = head->next;l->next = head;pre = l;// int x = pre->next->val;p = head; while(p != NULL && p->next != NULL){if(p->val == s->val){while(p->val == s->val && s->next != NULL){q = s;s = s->next;p->next = s;free(q);}if(s->val == p->val && s->next == NULL){p = NULL;pre->next = p;break;}q = p;pre->next = q->next;free(q);// pre = pre->next;p = pre->next;s = p->next;}else{pre = p;p = s;s = s->next;}}return l->next;} 相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

// 觉得优雅的不太优雅代码struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode *s = (struct ListNode *)malloc(sizeof(struct ListNode)*1);struct ListNode * a, * b,* a_x,* b_x;a = headA;b = headB;int len = 0;int flag = 1;while(a != NULL && b != NULL){a = a->next;b = b->next;}while(a!= NULL){len++;flag = 1;a = a->next;}while(b!= NULL){len++;flag = 0;b = b->next;}a_x = headA;b_x = headB;while(len > 0){if(flag == 0)b_x = b_x->next;elsea_x = a_x->next;len--;}while(a_x != NULL){if(a_x == b_x)return a_x;else{a_x = a_x -> next;b_x = b_x -> next;}}return NULL;}// 觉得不优雅的优雅代码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;} 链表中环的入口点

首先快慢指针一起走,直到相遇。然后将快指针置为头节点,快慢指针同步向前走,相遇就是入口节点。

struct ListNode *detectCycle(struct ListNode *head) {struct ListNode *slow = head;struct ListNode *first = head;while(1){if(first == NULL || first -> next == NULL)return NULL;slow = slow -> next;first = first -> next -> next;if(first == slow)break;}first = head;int k = 0;while(first != slow){first = first -> next;slow = slow -> next;k++;}return slow;} 反转链表 struct ListNode* reverseList(struct ListNode* head){struct ListNode* pre;struct ListNode* a;struct ListNode* end;pre = NULL;a = head;while(a != NULL){end = a->next;a->next = pre;pre = a;a = end;}return pre;} 旋转链表

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

struct ListNode* rotateRight(struct ListNode* head, int k){if(head == NULL)return NULL;if(head->next == NULL)return head;struct ListNode* slow,* first;struct ListNode* s = head;int len = 0;while(s!= NULL){s = s->next;len++;}k = k%len;// printf("%d",k);if(k == 0)return head;struct ListNode* lnode = (struct ListNode* )malloc(sizeof(struct ListNode)*1);lnode->next = head;slow = first = lnode;while(k--){first = first->next;}while(first->next != NULL){slow = slow->next;first = first->next;}struct ListNode* l;l = slow->next;slow->next = NULL;slow = l;// if(slow == head)// return head;while(l->next != NULL && l != NULL){l = l->next;}l->next = head;return slow;} 合并两个链表

给你两个链表 list1 和 list2 ,它们包含的元素分别为 n 个和 m 个。

请你将 list1 中下标从 a 到 b 的全部节点都删除,并将list2 接在被删除节点的位置。

下图中蓝色边和节点展示了操作后的结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g4yNwfV8-1657848413468)(images/code/fig1.png)]

请你返回结果链表的头指针。

struct ListNode* mergeInBetween(struct ListNode* list1, int a, int b, struct ListNode* list2){struct ListNode* s;struct ListNode* pre;struct ListNode* f;s = list1;int cha = b - a;while(--a)s = s->next;pre = s;s = s->next;while(cha--){f = s;s = s->next;free(f);}pre -> next = list2;while(pre -> next != NULL)pre = pre->next;pre->next = s->next;return list1;} 重排链表

给定一个单链表 L 的头节点 head ,单链表 L 表示为:

L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

struct ListNode* reverseList(struct ListNode* head) {struct ListNode thead;thead.next = NULL;struct ListNode* pre = &thead, *cur = head, *nxt = NULL;while (cur) {nxt = cur->next;cur->next = pre->next;pre->next = cur;cur = nxt;}return thead.next;}void reorderList(struct ListNode* head){if (head == NULL) return head;struct ListNode *fp = head, *sp = head;while (fp->next && fp->next->next) {fp = fp->next->next;sp = sp->next;}struct ListNode *sh = reverseList(sp->next);sp->next = NULL;struct ListNode *th = head, *tp = NULL;while (th && sh) {tp = sh->next;sh->next = th->next;th->next = sh;th = sh->next;sh = tp;}return head;} 链表排序——插入 struct ListNode* insertionSortList(struct ListNode* head){if(head == NULL || head->next == NULL)return head;struct ListNode *l = (struct ListNode *)malloc(sizeof(struct ListNode));l->val = 0;l->next = head;struct ListNode *pre = head;struct ListNode *cur = head->next;//cur外循环遍历while (cur != NULL){if(pre->val val)pre = pre->next;else{struct ListNode *move = l;while(move->next->val val)move = move->next;pre->next = cur->next;cur->next = move->next;move->next = cur;}cur = pre->next;}return l->next;} 链表排序——归并 struct ListNode * merge(struct ListNode *m,struct ListNode *n){struct ListNode *d = (struct ListNode *)malloc(sizeof(struct ListNode)*1);struct ListNode *head = d;while(m!=NULL && n!=NULL){if(m->val val){head->next = m;head = head->next;m = m->next;}else{head->next = n;head = head->next;n = n->next;}}if(m!=NULL) head->next = m;if(n!=NULL)head->next = n;return d->next;}struct ListNode* mergesort(struct ListNode *low,struct ListNode *mid){if(low == NULL)return NULL;if(low -> next == mid){low->next = NULL;return low;}//归并struct ListNode *s = low;struct ListNode *f = low;while(f != mid && f->next != mid){s = s->next;f = f->next->next;}return merge(mergesort(low,s),mergesort(s,mid));}struct ListNode* sortList(struct ListNode* head){if(head == NULL) return NULL;return mergesort(head,NULL);} 二叉树 中序遍历 // 递归void inorder(struct TreeNode* root,int returns[],int *returnSize){if(root == NULL)return;inorder(root->left,returns,returnSize);returns[(*returnSize)++] = root->val;inorder(root->right,returns,returnSize);}// 非递归int* inorderTraversal(struct TreeNode* root, int* returnSize){*returnSize = 0;int* returns = (int *)malloc(sizeof(int )*110);struct TreeNode *s[110];int top = 0;struct TreeNode *m = root;while(m!=NULL || top != 0){if(m){s[top++] = m;m = m->left;}else{m = s[--top];returns[(*returnSize)++] = m->val;m = m -> right;}}return returns;} 前序遍历 // 递归void preorder(struct TreeNode* root,int returns[],int *returnSize){if(root == NULL) return;returns[*returnSize] = root->val;(*returnSize)++;preorder(root->left,returns,returnSize);preorder(root->right,returns,returnSize);}// 非递归typedef struct stack{struct TreeNode* data[110];int top;}stack;void push(stack *s,struct TreeNode *x){s->data[(s->top)] = x;(s->top)++;}struct TreeNode *pop(stack *s,struct TreeNode *x){x = s->data[--(s->top)];return x;}void init(stack *s){(s->top) = 0;}int empty(stack s){if(s.top == 0)return 0;return 1;}void visit(struct TreeNode* x,int returns[],int *returnSize){returns[(*returnSize)++] = x->val;}int* preorderTraversal(struct TreeNode* root, int* returnSize){*returnSize = 0;int* returns = (int *)malloc(sizeof(int)* 110);struct TreeNode *m;m = root;stack s;init(&s);while(m != NULL || empty(s)!= 0){if(m){visit(m,returns,returnSize);push(&s,m);m = m->left;}else{m = pop(&s,m);m = m->right;}}return returns;} 后序遍历 // 递归void postorder(struct TreeNode* root,int returns[],int *returnSize){if(root == NULL) return;postorder(root->left,returns,returnSize);postorder(root->right,returns,returnSize);returns[(*returnSize)++] = root->val;}// 非递归int* postorderTraversal(struct TreeNode* root, int* returnSize){*returnSize = 0;int *returns = (int *)malloc(sizeof(int)* 110);struct TreeNode* data[110];int top = 0;struct TreeNode* m = root;struct TreeNode* pre = NULL;while(m || top != 0){while(m){pre = m;data[top++] = m;m = m->left;}m = data[--top];if(m->right != NULL && m->right != pre){data[top++] = m;m = m->right;}else{pre = m;returns[(*returnSize)++] = pre->val;m = NULL;}}return returns;} 二叉树的层序遍历

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

// em 优雅!// bfs 模板题 一层一层访问void bfs(struct TreeNode* root,int **returns,int *returnSize,int **returnColumnSizes){int front = 0;int rear = 0;struct TreeNode* queue[1010];queue[rear++] = root; while(front != rear){int cha = rear - front;returns[(*returnSize)] = (int *)malloc(sizeof(int)*(cha));for(int i = 0;i val;if(queue[front]->left != NULL)queue[rear++] = queue[front]->left;if(queue[front]->right != NULL)queue[rear++] = queue[front]->right;front++;}(*returnColumnSizes)[*returnSize] = cha; //这句zhejvlueluelue(*returnSize)++;}}int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){*returnSize = 0;if(root == NULL)return NULL;int **returns = (int **)malloc(sizeof(int*)*1010);*returnColumnSizes = (int *)malloc(sizeof(int)*1010); bfs(root,returns,returnSize,returnColumnSizes);return returns;} 前序 + 中序 构建二叉树 /*给定二叉树的前序和中序遍历序列,还原二叉树先序遍历访问顺序是:根 左 右中序遍历访问顺序是:左 根 右则通过先序遍历的根,可以将中序遍历分成左右两个部分,然后将左右两个部分分别生成左右子树*/struct TreeNode* dfs(int preorder[],int p_start,int p_end,int inorder[],int i_start,int i_end){if(p_start == p_end)return NULL;int root = preorder[p_start];int i_index;for(int i = i_start;i val = root;t->left = dfs(preorder,p_start+1,p_start+p_num+1,inorder,i_start,i_index);t->right = dfs(preorder,p_start+p_num+1,p_end,inorder,i_index+1,i_end);return t;}struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){return dfs(preorder,0,preorderSize,inorder,0,inorderSize);} 有序数组转为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

struct TreeNode* dfs(int returns[],int low,int high){if(low > high)return NULL;int mid = (low + high)/2;struct TreeNode *t = (struct TreeNode* )malloc(sizeof(struct TreeNode)*1);t->val = returns[mid];t->left = dfs(returns,low,mid-1);t->right = dfs(returns,mid+1,high);return t;}struct TreeNode* sortedArrayToBST(int* nums, int numsSize){return dfs(nums,0,numsSize-1);} 将二叉搜索树变平衡

给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。

如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二叉搜索树是 平衡的 。

如果有多种构造方法,请你返回任意一种。

struct TreeNode* dfs(int returns[],int low,int high){if(low > high)return NULL;int mid = (low + high)/2;struct TreeNode *t = (struct TreeNode* )malloc(sizeof(struct TreeNode)*1);t->val = returns[mid];t->left = dfs(returns,low,mid-1);t->right = dfs(returns,mid+1,high);return t;}void visit(struct TreeNode* root,int returns[],int *returnSize){if(root == NULL)return;visit(root->left,returns,returnSize);returns[(*returnSize)++] = root->val;visit(root->right,returns,returnSize);}struct TreeNode* balanceBST(struct TreeNode* root){//先遍历 存储到一个数组中,将整棵树 以一个 升序序列存放int *returns = (int *)malloc(sizeof(int)* 10010);int returnSize = 0;visit(root,returns,&returnSize);//再以中间建立 二叉搜索平衡树return dfs(returns,0,returnSize-1);} 二叉树的最近公共祖先

最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */struct TreeNode* dfs(struct TreeNode* root,struct TreeNode* p,struct TreeNode* q){struct TreeNode* l,* r;if(root == NULL)return NULL;if(root == p || root == q)return root;l = dfs(root->left,p,q);r = dfs(root->right,p,q);if(l != NULL && r != NULL)return root;else if(l == NULL && r!= NULL)return r;elsereturn l;}struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {//已知层序遍历的数组return dfs(root,p,q);} 层数最深的叶子节点的和

给你一棵二叉树的根节点 root ,请你返回 层数最深的叶子节点的和 。

/*通过三个参数分别记录递归过程中 达到的最大深度(max_deepth),当前的深度(deepth),最大深度的和(sum)如果达到新的最大深度,更新最大深度,最大深度和归零如果当前节点是叶子节点,判断当前深度是否是最大深度,如果是,将当前节点的值累加到最大深度和*//** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */struct TreeNode* dfs(struct TreeNode* root,int deepth,int * sum,int *max_deepth){if(root == NULL)return NULL;if(deepth > (*max_deepth)){(*max_deepth) = deepth;(*sum) = 0; //guiling heihei}struct TreeNode *left,*right;left = dfs(root->left,deepth+1,sum,max_deepth);right = dfs(root->right,deepth+1,sum,max_deepth);if(left == NULL && right == NULL && deepth == (*max_deepth))(*sum) += root->val;return root;}int deepestLeavesSum(struct TreeNode* root){int sum = 0;if(root == NULL)return 0;int max_deepth = 0;dfs(root,0,&sum,&max_deepth);return sum;} 对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

bool dfs(struct TreeNode* left_,struct TreeNode* right_){if(left_ == NULL &&right_ == NULL)return true;if(left_ == NULL || right_ == NULL || right_->val != left_->val)return false;// 左的左子树和右的右子树左的右子树和右的左子树 均互相对称return dfs(left_->left,right_->right) && dfs(left_->right,right_->left);}bool isSymmetric(struct TreeNode* root){if(root == NULL)return true;return dfs(root->left, root->right);} 二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

/*bfs 记录每一层的最后一个节点*/int* rightSideView(struct TreeNode* root, int* returnSize){*returnSize = 0;if(root == NULL)return NULL;int *returns = (int *)malloc(sizeof(int)*110);struct TreeNode* queue[120];int front = 0;int rear = 0;memset(returns,0,sizeof(returns));queue[rear++] = root;while(front != rear){int cha = rear - front;while(cha--){if(queue[front]->left != NULL)queue[rear++] = queue[front]->left;if(queue[front]->right != NULL)queue[rear++] = queue[front]->right;front++;}returns[(*returnSize)++] = queue[front-1]->val;}return returns;} 排序

本来想粘过来的 想想还是算了 直接上大佬的博客

插入 冒泡 选择

em 首先有请n 2n^2n2 的登场

biu:(25条消息) 排序算法总结—时间复杂度O(n^2)—冒泡/插入/选择小记_一君子兮-CSDN博客

希尔 快排 堆排 归并

然后是 n ∗ l og nn*log_nn∗logn​ di

biu:(25条消息) leetcode排序算法总结—时间复杂度o(nlogn)-希尔/堆排/快排/归并小记_一君子兮-CSDN博客

基数 计数

最后是 n 啦

biu:(25条消息) 排序算法总结—时间复杂度O(n)—基数排序/计数排序小记_一君子兮-CSDN博客

双轴快排 void swap(int *a,int *b){int t = *a;*a = *b;*b = t;}void sort(int *nums,int start,int end){if(start > end) return;int left = start;int right = end;if(nums[start] == nums[end]){for(int i = start;i nums[end])swap(&nums[start],&nums[end]);int privot1 = nums[start];int privot2 = nums[end];while(left+1 privot2)right--;int k = left+1; while(k

相关推荐: