常用算法模板
BFS
单向BFS
不记录层数
while queue 不空:
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未访问过:
queue.push(该节点)
作者:负雪明烛
链接:https://leetcode.cn/problems/01-matrix/solutions/203364/tao-lu-da-jie-mi-gao-dong-ti-mu-kao-cha-shi-yao-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
记录层数
level = 0
while queue 不空:
size = queue.size()
while (size --) {
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未被访问过:
queue.push(该节点)
}
level ++;
作者:负雪明烛
链接:https://leetcode.cn/problems/01-matrix/solutions/203364/tao-lu-da-jie-mi-gao-dong-ti-mu-kao-cha-shi-yao-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
双向BFS
// d1、d2 为两个方向的队列
// m1、m2 为两个方向的哈希表,记录每个节点距离起点的
// 只有两个队列都不空,才有必要继续往下搜索
// 如果其中一个队列空了,说明从某个方向搜到底都搜不到该方向的目标节点
while(!d1.isEmpty() && !d2.isEmpty()) {
if (d1.size() < d2.size()) {
update(d1, m1, m2);
} else {
update(d2, m2, m1);
}
}
// update 为将当前队列 d 中包含的元素取出,进行「一次完整扩展」的逻辑(按层拓展)
void update(Deque d, Map cur, Map other) {}
作者:宫水三叶
链接:https://leetcode.cn/problems/word-ladder/solutions/831894/gong-shui-san-xie-ru-he-shi-yong-shuang-magjd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
排序
插入排序
void insertSort(int a[],int n){
int i, j;
for(i = 1; i < n; ++i){
if(a[i] < a[i - 1]){
int temp = a[i];
// 依次查看前面是不是还有比自己大的元素
for(j = i - 1; j >= 0 && a[j] > temp; --j){
a[j + 1] = a[j];
} // for
a[j + 1] = temp;
} // if
} // for
}
折半插入排序
void insertBinarySort(int a[],int n){
int i, j;
for(i = 1; i < n; ++i){
if(a[i] < a[i - 1]){
int temp = i;
int low = 0;
int high = i - 1;
// 二分查找
while(low <= high){
int mid = (high - low) / 2 + low;
// 为了保证插入排序稳定性,在相等时候low = mid + 1
if(a[mid] == temp || a[mid] < temp){
low = mid + 1;
}else{
high = mid - 1;
} // else
} // while
for(j = i - 1; j >= low; --j){
a[j + 1] = a[j];
}
a[low] = temp;
}
}
}
选择排序
void selectSort(int a[], int n){
for(int i = 0; i < n - 1; ++i){
int min = i;
for(int j = i + 1; j < n; ++j){
if(a[j] < a[min]){
min = j;
}
if(min != i){
swap(a[i], a[min]);
}
} // for
}
}
快速排序
int getMid(int start, int end){
int mid = start + (end - start) / 2;
int Sum = a[start] + a[mid] + a[end];
int Max = max(max(a[start], a[mid]), a[end - 1]);
int Min = min(min(a[start], a[mid]), a[end - 1]);
int Mid = Sum - Max - Min;
if(Mid == a[start])
return start;
else if(Mid == a[mid])
return mid;
else
return end - 1;
}
int partition(int start, int end){
int pos = getMid(start, end);
int key = a[pos];
swap(a[pos], a[end - 1]);
int i = start, j = end - 1;
while(i < j){
// 两个指针轮流遍历
for(; i < j; ++i){
if(a[i] > key){
a[j] = a[i];
break;
} // if
} // for
for(; i < j; --j){
if(a[j] < key){
a[i] = a[j];
break;
} // if
} // for
} // while
a[i] = key;
return i;
}
void quickSort(int start, int end){
if(start + 1 < end){
int pos = partition(start, end);
quickSort(start, pos);
quickSort(pos + 1, end);
}
}
归并排序
void myMerge(int a[], int left, int right){
int mid = left + (right - left) / 2;
int nl = mid - left, nr = right - mid;
int l[nl], r[nr];
for(int i = 0; i < nl; ++i)
l[i] = a[left + i];
for(int i = 0; i < nr; ++i)
r[i] = a[mid + i];
int k = left, i = 0, j = 0;
while(i < nl && j < nr && k < right){
if(l[i] <= r[j]){
a[k] = l[i];
++i, ++k;
}else{
a[k] = r[j];
++j, ++k;
} // else
} // while
while(i < nl && k < right){
a[k] = l[i];
(void) (++i), ++k;
} // while
while(j < nr && k < right){
a[k] = r[j];
(void) (++j), ++k;
} // while
}
void mergeSort(int *a, int left, int right){
if(left + 1 < right){
int mid = left + (right - left) / 2;
mergeSort(a, left, mid);
mergeSort(a, mid, right);
myMerge(a, left, right);
}
}
拓扑排序
模板题:
二分搜索
int bsearch_1(int left, int right)
{
while (left < right)
{
int mid = (right - left) / 2 + left;
if (check(mid)) right = mid;
else left = mid + 1;
}
return left;
}
作者:林小鹿
链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solutions/955576/tu-jie-er-fen-zui-qing-xi-yi-dong-de-jia-ddvc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
int bsearch_2(int left, int right)
{
while (left < right)
{
int mid = (right - left + 1) / 2 + left;
if (check(mid)) left = mid;
else right = mid - 1;
}
return left;
}
作者:林小鹿
链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solutions/955576/tu-jie-er-fen-zui-qing-xi-yi-dong-de-jia-ddvc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
双指针/滑动窗口
1. 定义需要用到的变量,如快慢指针int slow = 0, int fast = 0; 输入的string s;
Hashmap char_freq用于记录string s当中slow到fast(包含)之间所有的字母出现的频率;
int longest记录符合题目要求的最长substring长度等
2. 定义双while循环
while fast < len(s):
char_freq[s[fast]] = char_freq.get(s[fast], 0) + 1
......
......
while 符合slow指针移动的条件:
char_freq[s[slow]] -= 1
......
......
slow += 1
if 符合某些判断条件:
longest = max(longest, fast - slow + 1)
fast += 1
return longest
Kruscal(含并查集)
#include <bits/stdc++.h>
#define mem(a, what) memset(a, what, sizeof(a))
#define INF 0x3f3f3f3f
#define MINF 0x3f
//#define _debug
//#define fre
using namespace std;
typedef pair<int, int> P;
struct Edge{
int from, to, weight;
Edge(){}
Edge(int from, int to, int weight){
this->weight = weight;
this->to = to;
this->from = from;
}
bool operator<(const Edge& other) const {
return weight < other.weight;
}
};
const int MAXN = 1000;
const int MAXM = 100000;
Edge edge[MAXM + 3];
int pre[MAXN + 3];
int n, m;
int ans;
void init(){
for(int i = 0; i <= MAXN; ++i){
pre[i] = i;
}
}
void merge(int r, int x){
int i = x, j;
while(pre[i] != r){
j = pre[i];
pre[i] = r;
i = j;
}
}
int find(int x){
int r = x;
while(r != pre[r])
r = pre[r];
merge(r, x);
return r;
}
bool mix(int a, int b){
int fx = find(a), fy = find(b);
if(fx == fy)
return false;
pre[fx] = fy;
return true;
}
int main(int argc, char *argv[]){
scanf("%d %d", &n, &m);
for(int i = 0; i < m; ++i){
scanf("%d %d %d", &edge[i].from, &edge[i].to, &edge[i].weight);
}
init();
sort(edge, edge + m);
for(int i = 0; i < m; ++i){
if(mix(edge[i].from, edge[i].to)){
ans += edge[i].weight;
}
}
printf("%d\n", ans);
return 0;
}