开发与面试涉及的基础数据结构和算法-Algorithm
来源:互联网 发布:宋徽宗 知乎 编辑:程序博客网 时间:2024/06/05 03:25
搜索
DFS 深搜方向:叶子数量级
1.排列级P(m,n)=m!/(m-n)!
int vis[n];dfs(int k){ if(k==n){ //执行P(m,n)次 return; } for(int i=0; i < n; i++) if(vis[i]){ vis[i]=1; dfs(k+1); vis[i]=0; }}
2.组合级C(m,n)=P(m,n)/m!
int vis[n];dfs(int k){ if(k==n){ //执行C(m,n)次 return; } for(int i=k; i < n; i++) dfs(k+1);}
3.记忆化:路径压缩
思想: 对于已经搜索过并足够小的路径,记忆搜索结果备下次使用
//并查集优化int parent(int x){ return (a[x]==x)? x : a[x]=parent(a[x]);}1. a+b组不成的最大数: dfs[x]=(dfs[x-a]||dfs[x-b])?1:0; if(!dfs[x])ans=max(ans,x);
BFS 宽搜
int g[n][n],vis[n],arr[n],ap=0;//初始化vis[0]=1;arr[ap++]=0;//遍历队列for(int i=0;i < ap; i++){ int k=a[i]; //code for deal node k; for(int j=0;j < n;j++){//拓展队列 if(g[k][j] && !vis[j]){ arr[ap++]=j; vis[j]=1; } }}
数论
//线性时间打素数表int arr[(int)(n/log(n)*1.5)],ap,vis[n];for(int i=2; i < n; i++){ if(!vis[i])arr[ap++]=i; for(int j=0; j < ap && i*a[j] < n;j++ ){ vis[i*a[j]]=1; if(i%a[j] == 0)break;//num=abx,其中a,b为素数,这样的num会被筛两次 }}
欧拉函数:euler(n)=n* (1-1/q[i]);其中q为n唯一分解素数,函数值是1-n中与n互素数的个数; 若 euler(n)=n-1则为素数;
互素测试(辗转相除):
int gcd(int x,int y){ return (y==0) ? x : gcd(y, x%y); //Fibonacci级减少}
图论
1. 最小生成树:连通一个图的所有节点,所消耗总代价最少(电话连线问题)2. Dijkstra最短路径:单源点到其他各点的最短路径 - O(n^2)3. Floyd最短路径:图中任意两点最短路径 - O(n^3)
贪心模型(启发式算法)
证明无后效性:对具有最优子结构的一维问题,每次决策都直接影响结果,并不可回退(前面状态->当前状态->后面状态);
1. 最优装载问题(部分背包问题):尽量装载单位体积价值大的物品2. Haffman可变长编码:出现频率高的字符,编码长度尽量短3. Prim算法:每次找出距离当前【集】最近的结点4. Dijkstra算法:每次找出距离【源点】最近的结点5. krusal算法:每次找出两个端点 不在同一集中 且 长度最短的边
分治模型
可分解:问题可分解成和原问题 性质相同 且 相互独立 的若干子问题;
可合并:若干子问题的解可合并得出原问题的解;
1. 二分法: 原问题分解成两段【快速幂】2. 第K小的数: [1,n]求k => [1,n/2)或(n/2,n]求k - 快排3. 逆序对数: 一个序列,相邻元素可以交换,求交换多少次序列有序 - 归并
动态规划模型
DP-贪心: DP中局部最优解不一定是全局最优解;
DP-分治: DP划分的子问题不具备独立性;
1. 阶段求解(递推式)
1. 上N阶台阶方案数: 一次上1阶或2阶,求上到n台阶的总方案数; 对于 i 台阶,能达到的台阶为 i-1和i-2; 故 a[i]=a[i-1]+a[i-2];2. RPG难题: 对于N个空位,使用R,P,G填充,要求相邻和首尾不同,求总方案数; 当i>=4时: 若 p[i-1] == p[0] 则 a[i]=2*a[i-1]; 若 p[i-1] != p[0] 则 a[i]=a[i-2];3. 危险的组合: 对于N个格子摆放0和1要求至少3个0连续摆放,求总方案数; 当i>=4时: 若前i-1个已经符合要求 则 a[i]=2*a[i-1] 若前i-1个不符合时i必须放0 则 a[i]=2^(i-3) - a[i-3];4. 全错位排列: 对于_(___) 若 _与(____)中恰好交换:a[i]=a[i-2]*(i-1) 若 _与(____)中不是交换:a[i]=a[i-1]*(i-1),此时把_在(___)中视为正确摆放5. 排队问题: 队伍中m个5和n个10,初始无5元找开,求合法排队方案数(同样钱的人交换视为同一种) 对于队伍m+n: 若最后一人持5元 则方案数 a[m][n] = a[m-1][n] 若最后一人持10元 则方案数 a[m][n] = a[m][n-1] 初始化:a[i][0]=1; a[i][i+x]=0;
2. 动态决策
1. 【线性】最长公共子序列: 对于每个i,讨论j=[1,n],dp[j]表示在逆序遍历j位置时最长公共序列长 从后往前遍历s和t, 若s[i]==t[j] 则 dp[j]=dp[j+1]+1; 否则 dp[j]=max(dp[j],dp[j+1]);最长上升子序列: 对于每个i,dp[i]表示在i位置的最长上升序列长度 顺序遍历a[N]:对于a[i]往前找到一个j使得a[i]>a[j] 则 dp[i]=dp[j]+1;3. 【背包】0-1背包问题:对于每个容量c放a[i]物品,放或不放形成两个决策结果 对于dp[c] 若c>=v[i] 则 dp[c]=max(dp[c-a]+v,dp[c]); 注意: 此处要求逆序遍历容量c;完全背包问题(物品无限) 同0-1背包问题状态转移 dp[c]=max(dp[c-a]+v,dp[c]); 注意: 对于容量要求顺序遍历,这样才能保证多次放入i物品DAG定点最长/短路径: 硬币找零问题,划分当前金额数为子结构 对于当前金额i dp[i]=max(dp[i-v[j]]+1,dp[i]) 注意: 对于当前金额要顺序遍历,保证同一硬币可以多次加入;6. 【划分】整数划分:把n划分为k份的方案数 对于dp[n][k] 若 n>=k dp[n][k]=dp[n-k][k]+dp[n][k-1]; 若 n < k dp[n][k]=dp[n][k-1]; 初始化: dp[n][1]=1;7. 【区域】石子合并:相邻合并若干堆石子,代价为w[i]+w[i+1],求最小总代价 对于dp[i][j]表示合并石子i->j的最优解;定义k=[i,j]则 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+w[j]-w[i-1]);最后值为dp[1][n]; 初始化: dp[i][j]=INF,dp[i][i]=0; w[i]表示1-i石子代价总和;Floyd: 找到一个中间点k,用k插入到所有的[i,j]区间并更新[i,j]区间长度9. 【树形】数字三角形 对于以i为根的树,dp[i]=dp[i]+max(dp[2*i],dp[2*i+1]);
DP问题:
1. 描述一个最优解的结构(划分问题)
2. 递归地定义最优解的值(状态转移)
3. “自底向上”计算最优解(初始化+记忆化搜索)
阅读全文
0 0
- 开发与面试涉及的基础数据结构和算法-Algorithm
- 面试涉及的网络基础
- 面试涉及的数据库基础
- Android中涉及数据结构和算法的工具类
- 面试涉及的java语言基础
- 面试中的涉及随机的算法
- [Algorithm] 九章一:算法面试与代码风格
- 面试涉及的框架与设计模式
- 面试专栏:算法与数据结构,虚拟机,Java基础,JavaWeb
- Android客户端面试基础(五)-数据结构与算法
- 数据结构与算法基础
- 数据结构与算法基础
- 基础数据结构与算法
- 数据结构与算法基础
- [算法]面试时的Java数据结构与算法
- 数据结构与算法面试总结
- 数据结构与算法面试总结
- 【面试笔试】数据结构与算法
- github初使用
- 应用上下文
- 不使用JQuery选择HTML Element
- bug君你好啊之servlet页面读取jsp的url的值显示为null
- leetcode 633. Sum of Square Numbers 二分查找
- 开发与面试涉及的基础数据结构和算法-Algorithm
- docker內安装TOPT
- caffe 模型 层次结构图
- 用蓝图实现模板化应用
- 数据结构实验之排序七:选课名单
- 如何生成指定均值和协方差矩阵的二维高斯分布数据
- IO操作-随机读取文件RandomAccessFile
- 数据库-6 一些有意思的东西
- viewpage