散列解决冲突的方法
- 开放定址法
- 链地址法
- 再哈希法
- 建立公共溢出区
快排
void sort(int[] a, int lo, int hi){
if(hi <= lo) return;
int i = lo, j = hi;
int v = a[lo];
while(i<j) {
while(a[i]<=v && i<j) i++;
while(v<a[j] && i<j) j--;
if(i==j) break;
swap(a[i],a[j]);
}
swap(a[lo],a[j]);
sort(a, lo, j-1);
sort(a, j+1, hi);
}
二叉堆
int[] pq;
int N = 0;
void swim(int k) { // 上浮
while(k>1 && pq[k/2]<pq[k]) {
swap(pq[k/2],pq[k]);
k /= 2;
}
}
void sink(int k) { //下沉
while(2*k <= N) {
int j = 2*k;
if(j<N && j<j+1) j++; // 找到两个子节点中较大的一个
if(k>=j) break; // 若比子节点都大则无需操作
swap(pq[k],pq[j]);
k = j;
}
}
void insert (int v) { // 插入时直接插入到最后,再上浮
pq[++N] = v;
swim(N);
}
int popMax() { // 删除时把最后一个元素与第一个元素交换,再下沉
int max=pq[1];
swap(pq[1],pq[N--]);
sink(1);
return max;
}
归并
void sort(int[] a, int lo, int hi){
if(hi <= lo) return;
int mid = lo + (hi-lo)/2;
sort(a, lo, mid);
sort(a, mid+1, hi);
// merge
int i = lo,j=mid+1;
for(int k = lo;k<=hi;k++) aux[k]=a[k];
for(int k = lo;k<=hi;k++) {
if(i > mid) a[k] = aux[j++];
else if(j > hi) a[k] = aux[i++];
else if(aux[j]<aux[i]) a[k] = aux[j++];
else a[k] = aux[i++];
}
}
二分查找
void rank(int[] a, int key, int N){
int lo=0, hi=N-1;
while(lo<=hi) {
int mid = lo +(hi-lo)/2;
if(key==a[mid]) return mid;
if(key<a[mid]) hi = mid-1;
else lo = mid+1;
}
return lo;
}
Shuffle
for i:=1 to n do swap(a[i], a[random(i,n)]);
洗牌算法shuffle
// Fisher-Yates
for(int i = n; i>=1; --i)
{
int j=rand(i);//生成1-i之间的随机数
exchange(A[i],A[j]);//交换A[i],A[j]
}
C++线程同步
http://www.cnblogs.com/jzincnblogs/p/5188051.html
多线程的几种加锁方式详解
http://blog.csdn.net/qq_35247219/article/details/51930849
后序遍历二叉树
void postorder(TreeNode* root, vector<int>& nodes) {
if (!root) return;
postorder(root -> left, nodes);
postorder(root -> right, nodes);
nodes.push_back(root -> val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> nodes;
postorder(root, nodes);
return nodes;
}
给一个先序序列,重构完全二叉树,如果是一般二叉树能不能重构,为什么
Longest Increasing Subsequence
时间复杂度O(n2)
dp数组记录以当前数字为结尾的子序列最长长度
第一层对每个元素a[i]遍历,更新dp数组
第二层对该元素前的每个元素a[j]遍历,若a[j]
Longest Common Substring
dp矩阵
若str1[i]==str2[j] 则dp[i][j]=dp[i-1][j-1]+1
否则dp[i][j]=max(dp[i-1][j],dp[i][j-1])
C++内存模型
http://www.cnblogs.com/Stultz-Lee/p/6751522.html
赛马问题
n*n个马,n个赛道
前n次分n组随机跑
第n+1次每组第一一起跑
根据这次排名可以知道各组的相对速度,接下来只需要考虑比较快的几组了
二叉树非递归前序遍历
对每个node
先输出node
然后node入栈
如果node有左子树
node=node->left
直到左下角的node
然后栈顶出栈
如果栈顶有右子树
node=node->right
void traverse(node* r) {
if(r==NULL) return;
stack<node *> s;
while(r!=NULL || !s.empty()) {
while(r!=NULL) {
cout<<r->key<<' ';
s.push(r);
r=r->left;
}
while(!s.empty()) {
r=s.top();
s.push();
r=r->right();
}
}
}
TCP拥塞控制
发送方维护拥塞窗口,窗口大小随是否拥塞而改变
慢开始:最初设置一个较小的窗口
http://blog.csdn.net/kinger0/article/details/48206999
一致性哈希
http://blog.csdn.net/cywosp/article/details/23397179/
TCP三次握手 四次挥手
http://www.jellythink.com/archives/705
随机发生P(1)=p,P(0)=1-p,如何得到1/2概率产生的0,1
若01则输出1,10则输出0
同理
001或110输出1,010或101输出2,100或011输出3
两个有序数组的中位数
http://blog.csdn.net/zcsylj/article/details/6802062
三种情况:
两数组中位数相等,则直接返回结果
A[i]>B[j],说明中位数在A[i/2]~A[i]区间,以及B[j]~B[j+j/2]区间
A[i]
判断链表是否有环
快慢指针
聚类
Kmeans聚类
选出k个质点,对所有点更新其最近的质点
不断重复直到质点位置不再改变
层次聚类
将最近的两个单位组合在一起成为一个新的单位
不断组合,直到最后只有少量单元
求最长重复子串
http://blog.csdn.net/renwotao2009/article/details/53039068
写出所有后缀子串
对后缀子串进行排序
比较相邻子串其公共前缀长度
GBDT
http://www.jianshu.com/p/005a4e6ac775
也就是说,当我们训练一个模型时,偏差和方差都得照顾到,漏掉一个都不行。
对于Bagging算法来说,由于我们会并行地训练很多不同的分类器的目的就是降低这个方差(variance) ,因为采用了相互独立的基分类器多了以后,h的值自然就会靠近.所以对于每个基分类器来说,目标就是如何降低这个偏差(bias),所以我们会采用深度很深甚至不剪枝的决策树。
对于Boosting来说,每一步我们都会在上一轮的基础上更加拟合原数据,所以可以保证偏差(bias),所以对于每个基分类器来说,问题就在于如何选择variance更小的分类器,即更简单的分类器,所以我们选择了深度很浅的决策树。
ROC
横轴:假正例率,即反例中被预测为正例的比例
纵轴:真正例率,即正例中被预测为正例的比例123