算法和数据结构总结

  本文是要将一些看过的算法进行总结,目的在于总结出对于什么题、什么特点、什么形式的题使用什么样的数据结构以及算法合适,或者反之。
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步的元素。

        某售货员要到若干城市去推销商品,一直各城市之间的路程,他要选定一条从驻地出发,经过每个城市一遍,最后回到住地的路线,使总的路程最短. 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值