算法和数据结构总结
2014-03-31 09:21
453 查看
本文是要将一些看过的算法进行总结,目的在于总结出对于什么题、什么特点、什么形式的题使用什么样的数据结构以及算法合适,或者反之。
1.bitmap
第一个只出现一次
2.hashmap
3.双指针、倍速指针、距离双指针、尾指针
最长回文子串、
4.stack、queue、vector
5.暴力、剪枝
6.贪心
7.DP
背包问题:放与不放、无穷背包问题。
格子取数问题-->考虑两步的DP
LCS问题:用二维图+箭头方向 用于分析的好例子
子数组的最大和:DP,以当前节点为例,考虑前一个节点和本节点得到最优就好,其他节点不管
8.递归、递推
全排列
递归中,如何对左子树最右节点和右子树最左节点同根节点进行操作:使用head,tail 节点连接。
详见微软100题:把二元查找树转变成排序的双向链表
9.查找:二分。。。
10.排序:堆排序、快排、归并
查找top10 ip:归并排序+topK算法
如何给10^7个数据量的磁盘文件排序:归并+topK
最大堆、最小堆:可以使用treenode,但用数组来表示树会方便很多。
11.trie、B、B+、B*、R树、后缀树
trie树用于单词检索
后缀树:寻找最长回文子串
12.数论
13.其他技巧
14.完美洗牌方法:可以将
a1,a2,a3,a4,b1,b2,b3,b4 变成 a1,b1,a2,b2,a3,b3,a4,b4
15.分治法
16.图及BFS、DFS
最小操作数:
17.回溯法+剪枝
回溯法是基本算法的一种,可以用于解决大致这样的问题(其实回溯法可以算是暴力搜索的一种变形,可以解决大部分的问题,因为搜索了所有可能的情况):假设我们有一个N个元素的集合{N},现在要依据该集合生成M个元素的集合{M},每一个元素的生成都依据一定的规则CHECK。
一般的,回溯法需要用一个数组记录解情况,一个数组记录节点是否被访问过的情况。
CodeFrame:
用回溯法解决此问题,我们可以划分为三个重要组成部分。
步骤
从第一步开始至第M步,每一步都从{N}中选取一个元素放入结果{M}中。
界定
每次选择一个元素时,我们都要用规则CHECK来界定{N}中的元素谁合适。界定规则的描述将决定算法的效率和性能。
回溯
如果第k步不能找到合适的元素或者需要得到更多的结果,返回到第k-1步,继续选择下一个第k-1步的元素。
例如:旅行售票员问题.
某售货员要到若干城市去推销商品,一直各城市之间的路程,他要选定一条从驻地出发,经过每个城市一遍,最后回到住地的路线,使总的路程最短.
1.bitmap
第一个只出现一次
2.hashmap
3.双指针、倍速指针、距离双指针、尾指针
最长回文子串、
4.stack、queue、vector
5.暴力、剪枝
6.贪心
7.DP
背包问题:放与不放、无穷背包问题。
输入两个整数n 和m,从数列1,2,3.......n 中随意取几个数, 使其和等于m ,要求将其中所有的可能组合列出来. 此题可使用01背包问题,放与不放的递归解法。 伪代码:p(i,v) if i=v cout find; if i>v return; p(i-1,v);//dont put in i p(i-1,v-i);//put in i
格子取数问题-->考虑两步的DP
LCS问题:用二维图+箭头方向 用于分析的好例子
子数组的最大和:DP,以当前节点为例,考虑前一个节点和本节点得到最优就好,其他节点不管
8.递归、递推
全排列
递归中,如何对左子树最右节点和右子树最左节点同根节点进行操作:使用head,tail 节点连接。
详见微软100题:把二元查找树转变成排序的双向链表
题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / \ 6 14 / \ / \ 4 8 12 16 转换成双向链表 4=6=8=10=12=14=16。 首先我们定义的二元查找树节点的数据结构如下: struct BSTreeNode {i nt m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node };ANSWER: This is a traditional problem that can be solved using recursion. For each node, connect the double linked lists created from left and right child node to form a full list. /** * @param root The root node of the tree * @return The head node of the converted list. */ BSTreeNode * treeToLinkedList(BSTreeNode * root) { BSTreeNode * head, * tail; helper(head, tail, root); return head; } void helper(BSTreeNode *& head, BSTreeNode *& tail, BSTreeNode *root) { BSTreeNode *lt, *rh; if (root == NULL) { head = NULL, tail = NULL; return; } helper(head, lt, root->m_pLeft); helper(rh, tail, root->m_pRight); if (lt!=NULL) { lt->m_pRight = root; root->m_pLeft = lt; } else { head = root; }i f (rh!=NULL) { root->m_pRight=rh; rh->m_pLeft = root; } else { tail = root; } }
9.查找:二分。。。
10.排序:堆排序、快排、归并
查找top10 ip:归并排序+topK算法
如何给10^7个数据量的磁盘文件排序:归并+topK
最大堆、最小堆:可以使用treenode,但用数组来表示树会方便很多。
11.trie、B、B+、B*、R树、后缀树
trie树用于单词检索
后缀树:寻找最长回文子串
12.数论
13.其他技巧
14.完美洗牌方法:可以将
a1,a2,a3,a4,b1,b2,b3,b4 变成 a1,b1,a2,b2,a3,b3,a4,b4
15.分治法
16.图及BFS、DFS
最小操作数:
17.回溯法+剪枝
回溯法是基本算法的一种,可以用于解决大致这样的问题(其实回溯法可以算是暴力搜索的一种变形,可以解决大部分的问题,因为搜索了所有可能的情况):假设我们有一个N个元素的集合{N},现在要依据该集合生成M个元素的集合{M},每一个元素的生成都依据一定的规则CHECK。
一般的,回溯法需要用一个数组记录解情况,一个数组记录节点是否被访问过的情况。
CodeFrame:
void Bcktrack(int t) //参数t表示当前递归深度 { if(t>n)Output(x); //遍历到解,则将解输出或其他处理 n用来控制递归深度即解空间树的高度 else { //f(n,t)和g(n,t)表示当前节点(扩展节点)处未搜索过的子树的起始编号和中指编号 for(int i=f(n,t);i<=g(n,t);i++) { x[t]=h(i); //h(i)表示当前节点(扩展节点)处x[i]的第i个可选值 if(Constarint(t)&&Bound(t)) //剪枝函数:约束函数,限界函数 Bcktrack(t+1); } } }
用回溯法解决此问题,我们可以划分为三个重要组成部分。
步骤
从第一步开始至第M步,每一步都从{N}中选取一个元素放入结果{M}中。
界定
每次选择一个元素时,我们都要用规则CHECK来界定{N}中的元素谁合适。界定规则的描述将决定算法的效率和性能。
回溯
如果第k步不能找到合适的元素或者需要得到更多的结果,返回到第k-1步,继续选择下一个第k-1步的元素。
例如:旅行售票员问题.
某售货员要到若干城市去推销商品,一直各城市之间的路程,他要选定一条从驻地出发,经过每个城市一遍,最后回到住地的路线,使总的路程最短.
相关文章推荐
- 常见数据结构与算法整理总结
- 总结回顾 - 数据结构和算法98(完)
- 前端学习总结(二十二)——常见数据结构与算法javascript实现
- 海量数据处理常用算法、数据结构总结
- 数据结构之第二章 算法分析总结 及 课后题答案
- 数据结构和算法总结
- 数据结构和算法面试总结
- 各种基本数据结构和算法总结清单
- 算法与数据结构-常用排序算法总结2-基数排序
- 常用数据结构和算法操作效率的对比总结
- 一张大图总结数据结构与算法
- 算法--基本数据结构总结
- 算法基础----关于数据结构中图的相关算法总结探究
- 数据结构(五)算法总结
- 面试题总结之MISC(操作系统,网络,算法和数据结构,数学,面向对象设计,软件开发,测试,工具)
- 算法思想及数据结构 -- 总结
- 计算机专业找工作面试面经总结(操作系统,数据库,数据结构,算法,虚拟化,编程实践等)
- Java 数据结构和经典算法经验总结
- 【数据结构】排序算法时间效率、空间效率以及算法稳定性总结
- 数据结构学习总结 —— 2.算法