1、对数组排序: sort(a,a+n,cmp)
对vector排序:sort(v.begin(),v.end(),cmp)
结构体的cmp
bool cmp(node a,node b){
if(a.x!=b.x) return a.x>b.x; //从大到小排 >
else return a.y<b.y //从小到大排 <
}
2、a与b之间建立一条边:edges[cnt++]={a.b};
3、并查集压缩路径的过程实际也是遍历树/图的过程
4、并查集合并:合并根节点且只保证根节点的size有意义
int pa=find(a),pa=find(b);
p[pa]=pb; //a合并到b
size[pb]+=size[pa]; //b根节点规模加上a的
5、比较a/b 与c/d 大小:转化为比较 a*d c*b
6、二叉搜索树建树(左小右大)
int k=0;
for(int i=0;i<n;i++){
insert(a[i],k);
}
void insert(int u,int &k){
if(!k) k=++idx,tree[idx]=u;
else if(u<=tree[k]) insert(u,l[k]);
else insert(u,r[k]);
}
遍历并记录层数
dfs(int u,int level){
if(u==0) return;
max_depth=max(max_depth,level);
dfs(l[u],level+1);
dfs(r[u],level+1);
}
7、字符串中取相同的连续子字符串(双指针)
for(int i=0;i<n;i++){
int j=i+1;
while(j<n&&str[j==str[i]) j++;
int len=j-i; //子字符串长度
i=j-1;
}
判断子串字符s是否连续出现k次 len%k==0
8、
sscanf(str,"%d",&n) 把字符数组str内容以%d格式写入n中(从左到右)
sprintf(str,"%d",n) 把n以%d格式写入字符数组str中(从右到左)
stof 用于将字符串转换为浮点数
函数原型float stof(const string& _Str, size_t *_Idx = 0);
如果无法转换会抛出异常,try catch写法:
bool res=true;
try{
size_t idx;
double x=stof(s,&idx);
if(idx<s.size()) res=false;
}
catch(...){
res=false;
}
PS:如果一段字符串后半截为非浮点数,用stof会自动转换合理的前半部分,因此还需判断 idx 和s.size()
字符数组函数str[] #include<string.h>:
strlen strcmp strcpy strcat
字符串函数 string #include<stirng>:
+= == …… length/size clear find replace
if(str.find(str2)!=string::npos)
string不能用printf直接输出: printf("%s",str.c_str
9、
stoi 字符串转整数; 头文件 #include<cstring>
判断完全二叉树(空结点只出现在最后一排的最右侧):
bfs遍历,将遍历的点加入数组,最后判断数组大小是否与结点数一致
void bfs(int u){
queue<int> q;
q.push(u);
while(!q.empty()){
int t=q.front();
q.pop();
res[p++]=t;
if(t!=-1) cnt++;
if(cnt==n){
last=t;
break;
}
q.push(Left[t]);
q.push(Right[t]);
}
}
9、u >>= 1 相当于将变量u的二进制表示向右移动一位,并将结果重新赋值给 u。
这种操作通常用于将数值除以2(在整数除法中,向下取整)
10、二叉树建树(中序+前序/后序可确定)
11、map哈希要考虑查找时间,当int范围可能很大时,用编号代替数值进行计算和查找(离散化)。如:
pre[i],in[i] 存储结点编号,而不是结点值本身
pos[pre[i]]=i 只需映射一次
12、找最低公共祖先(LCA):爬山法,比较两个结点深度,深度高的向上爬找父亲结点
int x=pos[a],y=pos[b];
while(x!=y){
if(depth[x]<depth[y]) y=father[y];
else x=father[x];
}
13、map找某个元素a是否存在 mp.count(a)==0;
清空vector vector.clear();
14、判断堆:从根节点到叶节点路径保持递增/递减
15、求叶结点到根结点距离(高度/边数)
(1)BFS
(2)dp 存储更方便 f[i]存i到root距离
dfs(int u){
if(f[u]!=-1) return f[u]; //f[u] 已存在
if(p[u]==-1) return 0;//根结点
return (dfs(p[u]) + 1);
}
16、次幂a^n: pow(a,n) #include<cmath>
17、四舍五入保留一位小数:
round(double(av_dis)*10/n)/10
round()本身为四舍五入保留整数 头文件#icnlude<cmath>-
18、strcmp 按字典序比较两个字符串大小
字符数组1<字符数组2 返回负整数;= 返回0; >返回正整数
例:if(strcmp(op,"push")==0)
19、set 内部自动升序且不含重复元素。
只去重不排序:unordered_set
不去重:multiset
只能通过迭代器访问
for(auo it=s.begin();it!=s.end();it++)
insert、find、size
stack没有insert 但可以pop push
20、树的度是指一个节点拥有的子节点的数量
21、从一个整数截取两个数,利用string拆分后再转为int:
例如167892提取 167 892
int len=num.size()/2;
int left=stoi(substr(0,len));
int right=stoi(substr(len));
22、判断是否在同一对角线(N皇后)
法1 正/左对角 y-x 相等,副/有对角 x+y相等
注意:y-x范围-(n-1)~(n-1) 加上偏移量n映射成正数
法2 将坐标系旋转x与y对调 变成都判断x+y是否相等
23、螺旋矩阵(以某种方向元素填充进矩阵,设定偏移量代表移动方向)
如:int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
上 右 下 左 顺时针
int r=1,c=1,x=1,y=1,d=1; //顺时针从向左走开始
for(int i=0;i<N;i++){
g[x][y]=number[i];//
r=x+dx[d],c=y+dy[d];
if(r<1||r>m||c<1||c>n||g[r][c]){
d=(d+1)%4;
r=x+dx[d],c=y+dy[d];
}
x=r,y=c;
}