算法与数据结构
灵神:如何科学刷题? https://leetcode.cn/discuss/post/3141566/ru-he-ke-xue-shua-ti-by-endlesscheng-q3yd/
新动计划: https://leetcode.cn/studyplan/primers-list/
提交之前检查:输入 输出\n return0
运行超时->去检查循环条件
| 结果 | 含义 | 核心排查方向 | 出错记录 |
|---|---|---|---|
| PE | 格式错误 | 空格 / 换行 / 大小写 / 输出顺序 / 字符宽度(如 %5d)/ 标点 | 打印时多了一个空格 |
| WA | 答案错误 | 逻辑漏洞、边界条件、数据类型溢出、特殊用例未处理(如 0 / 负数 / 极值) | 边界0没处理 |
| RE | 运行时错误 | 数组越界、除 0、空指针、栈溢出、递归爆栈、scanf 参数漏 & | |
| TLE | 超时 | 算法复杂度太高、死循环、不必要的重复计算 | |
| MLE | 内存超限 | 数组开太大、内存泄漏、重复申请内存 | |
| CE | 编译错误 | 语法错误(少分号 / 括号)、头文件缺失、变量未定义、数据类型写错 |
平衡二叉树要求所有节点的左右子树高度差≤1
C语言零碎点
| 格式符 | 含义 |
|---|---|
%5d |
输出整数,占 5 个字符宽度,向右对齐;若数字长度 < 5,左侧补空格;若≥5,按实际长度输出 |
%-5d |
输出整数,占 5 个字符宽度,向左对齐;若数字长度 < 5,右侧补空格(对比用) |
在竞赛题中,优先用 double 而非 float ,原因是精度更高、避免计算误差。
快速排序:C 语言标准库提供了函数qsort(nums, numsSize, sizeof(int), cmp)(基于快速排序实现),是算法题中排序的首选。(#include <stdlib.h>)
https://www.doubao.com/thread/wc1aabd99c6e3524c
1 | //cmp |
一个简单的排序来练手:L1-010 比较大小 - 团体程序设计天梯赛-练习集
四舍五入:(N+1)/2 等价于 N/2 向上取整。
按位异或的运算符在 C 语言中是 ^,运算规则是:对两个数的二进制每一位逐一比较,相同为 0,不同为 1。
int在C语言里面的范围是-2^31到2^31-1。
231. 2 的幂 - 力扣
◆关于字符串
1 | char num[20]; |
fgets是读取含空格字符串的标准方法(会读取‘\0’),参数含义:fgets(数组名, 最大长度, 输入流); 输入流一般是stdin。
c语言的字符串以'\0'(ASCII 码 0)结尾。
ASCLL码:
- 大写字母 A-Z 的 ASCII 码范围:65-90
- 小写字母 a-z 的 ASCII 码范围:97-122
- 同一字母的小写比大写大 32(如 A=65,a=97,97-65=32)
#include <string.h>字符串库函数:
strlen(n)获得该字符串的长度(不包含\0)。strcpy(m, n)把第二个字符串n的内容拷贝到第一个字符串m中。memcpy(m, n, num)将内存地址n处的num 个字节的数据,拷贝到内存地址m处。strcspn(strs, "\n")会扫描字符串strs,找到第一个出现的\n(换行符),返回它的下标。如果strs里没有\n(比如读取的字符串长度刚好到 10000),就返回strs的总长度(strlen(strs))。
◆关于数组
三种声明方式
- 数据类型
数组名称[长度n]= {元素1,元素2…元素n}; - 数据类型
数组名称[长度n]; - 数据类型
数组名称[]= {元素1,元素2…元素n};
1 | // 输入一个不超过 1000 位的正整数N。 |
memset(cnt, 0, sizeof(cnt)):批量初始化 cnt 数组为 0,第三个参数表示总字节数。
1365. 有多少小于当前数字的数字 - 力扣(LeetCode)
◆关于指针int* arr 和 int *arr 是等价写法。
1 | int arr[5] = {1,2,3,4,5}; |
返回指针类型的函数,return p而不是return *p,如果是后者,那么函数返回类型应该是int。
int *P=(int*)malloc(sizeof(int)*1)为指针分配空间的函数。free(p);//回收int *p = (int*)calloc(4, sizeof(int)) 为指针分配空间的函数并初始化为0。(<stdlib.h>)
realloc(原内存指针, 新的内存大小) 是 C 语言标准库(<stdlib.h>)中的函数,全称re-allocate,作用是调整已分配堆内存的大小,让内存 “按需分配”,避免浪费。
1 | // 第一步:预分配“足够大”的内存(比如这里先分配最多的2*n个空间) |
其他函数llabs() 函数:全称 long long absolute value,作用是返回 long long 类型的绝对值(对应 int 类型的 abs())。
数学
闰年的判别条件是:该年年份能被4整除但不能被100整除,或者能被400整除。闰年的2月有29天。
素数(质数)的定义:大于 1 的自然数,除了 1 和它本身,不能被其他自然数整除。
向上取整:
12/5 = 2.4→ 向上取整 = 3;10/5 = 2.0→ 向上取整 = 2;7/3 = 2.333→ 向上取整 = 3;0/5 = 0→ 向上取整 = 0。(a + b - 1) / b实现向上取整。
| 取整需求 | 公式(整数除法) | 例题 |
|---|---|---|
| 向上取整 | (a + b - 1) / b |
码蹄集OJ-小码哥的魔法实战1 |
| 向下取整 | a / b |
|
| 四舍五入 | (a + b/2) / b |
圆周长:C=2πr;面积:S=πr2;直径:d=2r
球体表面积:S=4*π*r^2;体积:V=3/4*π*r^3
辗转相除法的数学原理
核心定理:gcd(a, b) = gcd(b, a % b)(a ≥ b > 0)
即「两个数的最大公约数」等于「第二个数」和「第一个数除以第二个数的余数」的最大公约数。
当余数为 0 时,此时的 a 就是最大公约数。
1 | // 辗转相除法求最大公因数(GCD) |
二进制与位运算
两大类:逻辑位运算符、位移运算符
位与& 二进制 同1异0
位或| 都为0才是0 其他全为1
异或^ 同0异1
按位取反 ~ 转化为二进制再取反
左移x<<y x转化为二进制,左移y位,末尾补0
右移x>>y x非负数,高位补0;x负数,高位补1。
C 语言中运算符的优先级:
==(相等判断) > &(按位与) > &&(逻辑与)
简单题
最大公约数和最小公倍数
1 |
|
计算天数
题目:在一行输出日期是该年中的第几天。
输入:2009/03/02
输出:61
1 |
|
输出整数各位数字
1 |
|
同类题目:将整型数x中每一位能被3整除的数依次取出。例如,当x中的数为:97653140时,px中的数为:9630;如果没有满足要求的数则输出x。
1 | void fun(int x, int *px) { |
同类题目:求一批整数中出现最多的个位数字
输入:3
1234 2345 3456
输出:3: 3 4
1 |
|
同类题目:输出一个整数的逆序数
1 | int reverse(int number) { |
判断是否是回文数:
如果输入是超大数(如1000000000000000000),int类型会溢出(int 最大约 21 亿)。
所以用指针字符串传参更好。
1 | int is_huiwen(char *nums){ |
字符串数字-1:
1 | char* str_decrease(char *p){ |
二叉树最大深度
1 | /** |
自上向下:
1 | /** |
◆类似题目:判断两棵树是否相同
- 终止条件:如果
p或q有一个是空节点 时, 只有当p和q都为空时才返回true,否则返回false。 - 递归条件:如果
p和q都非空 → 必须满足 3 个条件才返回true。- 当前节点值相等(
p->val == q->val) - 左子树完全相同(
isSameTree(p->left, q->left)) - 右子树完全相同(
isSameTree(p->right, q->right))
- 当前节点值相等(
- 只要有一个条件不满足,整体返回false。
1 | bool isSameTree(struct TreeNode* p, struct TreeNode* q) { |
◆类似题目:判断是否是对称树
1 | bool isSameTree(struct TreeNode* left, struct TreeNode* right){ |
◆类似题目:平衡二叉树 110. 平衡二叉树 - 力扣(LeetCode)
排序
561. 数组拆分 - 力扣(LeetCode)
快速排序+偶数下标求和:
1 | int cmp(const void* a, const void* b){ |



