Tree
Binary Tree
1
2
3
4
5
6
7
8
9
10
11
12
13
| /* *
* Definition for a binary tree node.
* From LeetCode.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right)
* : val(x), left(left), right(right) {}
* };
*/
|
Delete a Node in Binary Tree
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| TreeNode* delete_node(TreeNode* root, int key) {
if(root==nullptr) return nullptr;
else if(root->val>key) {
root->left=delete_node(root->left, key);
}
else if(root->val<key) {
root->right=delete_node(root->right, key);
}
else {
if(root->left==nullptr) return root->right;
else if(root->right==nullptr) return root->left;
else {
TreeNode* new_root=root->right;
while(new_root->left!=nullptr) new_root=new_root->left;
new_root->right=delete_node(root->right, new_root->val);
new_root->left=root->left;
return new_root;
}
}
return root;
}
|
Segment Tree
My Calendar III (Also Differentiation & Prefix Sum)
Segment Tree OI-WIKI
Segment Tree is efficient to tell how many times a point has appeared in a segment.
Trie (Prefix Tree)
Implement Trie
String
Split
C++ string doesn’t have built-in split function. To split string into an array of substrings by a character,
1
2
3
4
5
6
7
8
9
| vector<string> split(string str, char c) {
stringstream ss(&str);
vector<string>res;
string temp;
while(getline(ss, temp, c)){
res.emplace_back(temp);
}
return res;
}
|
KMP
Heuristic string matching algorithm time complexity is O(m*n). KMP (Knuth Morris Pratt) Pattern Searching algorithm uses the previous matching result to optimize the searching process.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| vector<int>longest_prefix_array;
void compute_longest_prefix_array(const string& pattern) {
longest_prefix_array.resize(pattern.size(), -1);
for(int i=1; i<pattern.size(); i++) {
int j=longest_prefix_array[i-1];
while(j!=-1&&pattern[j+1]!=pattern[i]) {
j=longest_prefix_array[j];
}
if(pattern[j+1]==pattern[i]) {
longest_prefix_array[i]=j+1;
}
}
}
bool kmp_search(const string& str, const string& pattern) {
compute_longest_prefix_array(pattern);
for(int i=1, j=-1; i<str.size()-1; i++) {
while(j!=-1&&pattern[j+1]!=str[i]) {
j=longest_prefix_array[j];
}
if(pattern[j+1]==str[i]) {
j++;
if(j==str.size()-1) return true;
}
}
return false; // mismatch
}
|
Sort
Insertion Sort
Insertion sort outperforms other sorting algorithms in small sizes and is stable.
1
2
3
4
5
6
7
8
9
10
11
| void insertion_sort(vector<int>& arr) {
for(int i=1; i<arr.size(); i++) {
int temp=arr[i], j=i;
// Move greater elements to positions of greater indexes
while(arr[j]>temp) {
arr[j+1]=arr[j];
j--;
}
arr[j+1]=temp;
}
}
|
Quick Sort
Quick Sort is preferred over Merge Sort for arrays.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| vector<int>arr;
/* This function takes last element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
int partition(int low, int high) {
int pivot=arr[high]; // pivot
// Index of smaller element
// and indicates the right position of pivot found so far
int i=(low-1);
for (int j=low; j<=high-1; j++) {
// If current element is smaller than the pivot
if (arr[j]<pivot) {
i++; // increment index of smaller element
swap(arr[i], arr[j]);
}
}
swap(arr[i + 1], arr[high]);
return (i + 1);
}
/* The main function that implements QuickSort
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void quickSort(int low, int high) {
if (low < high) {
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(low, high);
// Separately sort elements before
// partition and after partition
quickSort(low, pi - 1);
quickSort(pi + 1, high);
}
}
|
Merge Sort
Merge Sort is preferred over Quick Sort for linked lists. Merge Sort
Hybrid Sort
Hybrid sort uses different sorting algorithms in different scenarios, and thus maintaining high performance across the cases.
For example, pattern defeating sort use insertion sort when the partition of target is slower than a preset threshold (24). For larger target size, it applies quicksort. Once it learns the partition of target is bad in its definition, it uses a fallback strategy (heap sort).
Other hybrid sorts include introsort, timsort, etc.
Heap
Stack
Random
Mersenne Twister (MT19937)
The Mersenne Twister is a general-purpose pseudorandom number generator (PRNG). Its name derives from the fact that its period length is chosen to be a Mersenne Prime. Read More on Wikipedia. MT19937 stands for mersenne twister with a long period of 219937 – 1 which means mt19937 produces a sequence of 32-bit integers that only repeats itself after 2^19937 – 1 number have been generated.
1
2
3
4
5
6
7
8
9
10
11
12
13
| #include <ctime>
#include <iostream>
#include <random>
using namespace std;
int main() {
// Using the constructor to
// initialize with a seed value
mt19937 mt(time(nullptr));
// Operator() is used to
// generate random numbers
cout << mt();
return 0;
}
|
Search
Binary Search
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // assume target in candidates
vector<int>candidates;
// return index of target in candidates
int binary_search(int target) {
int low=0, high=candidates.size();
while(low<high) {
int mid=(high-low)/2+low;
if(candidates[mid]==target) {
return mid;
} else if(candidates[mid]>target) {
high=mid;
} else {
low=mid+1;
}
}
return low;
}
|
Union Find
With Path Compression
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| class UnionFind {
public:
UnionFind(int n) {
for(int i=0; i<n; i++) {
parent.push_back(i);
rank.push_back(0);
}
}
int find(int x) {
if(parent[x]!=x) {
parent[x]=find(parent[x]);
}
return parent[x];
}
void unite(int x, int y) {
x=find(x);
y=find(y);
if(x==y) return;
if(rank[x]<rank[y]) {
parent[x]=y;
} else {
parent[y]=x;
if(rank[x]==rank[y]) rank[x]++;
}
}
bool same(int x, int y) {
return find(x)==find(y);
}
private:
vector<int>parent;
vector<int>rank;
};
|