有很多的基础算法经常会用到,但是又容易写错。而网上查到的实现又五花八门、良莠不齐,故在此整理记录。
本文的目录如下:
1.二分查找 2.并查集 3.最大公约数 4.Trie树(前缀树)
1.二分查找
一个细节就是计算middle时,用 (left + right) / 2 容易数值溢出,所以改成 middle = left + (right - left) / 2.
c++实现:
#define LEFT_BOUND 0
#define RIGHT_BOUND 100
int check(const int &middle){
// TODO: return -1 or 0 or 1
}
int main() {
int left = LEFT_BOUND, right = RIGHT_BOUND;
int middle, flag;
while (left <= right){
middle = left + (right - left) / 2; // 防数值溢出
flag = check(middle);
if (flag == 0){
return middle;
}
else if (flag == -1){
left = middle + 1;
}
else{
right = middle - 1;
}
}
return -1;
}
2.并查集
c++实现:
// Union-Find Set, STL style
class UF {
public:
UF(int n) {
count = n;
for (int i = 0; i < n; ++i) {
parent.push_back(i);
rank.push_back(0);
}
}
int find(int i) { // path compression
if (parent[i] != i) parent[i] = find(parent[i]);
return parent[i];
}
void Union(int x, int y) { // union with rank
int rootx = find(x);
int rooty = find(y);
if (rootx != rooty) {
if (rank[rootx] > rank[rooty]) parent[rooty] = rootx;
else if (rank[rootx] < rank[rooty]) parent[rootx] = rooty;
else {
parent[rooty] = rootx; rank[rootx] += 1;
}
--count;
}
}
int size() const {
return count;
}
void clear() {
parent.clear();
rank.clear();
count = 0;
}
private:
vector<int> parent;
vector<int> rank;
int count; // # of connected components
};
3.最大公约数
c++实现:
// while实现
int gcd(int a, int b){
while (b != 0){
int tmp = a % b;
a = b;
b = tmp;
}
return a;
}
// 递归实现
unsigned int gcd(unsigned int a, unsigned int b) {
return b == 0 ? a : gcd(b, a % b);
}
4.Trie树(前缀树)
c++实现:
class Trie{
public:
bool isLeaf = false;
Trie* next[26] = { nullptr };
Trie() {}
void insert(const string& word) {
Trie* root = this;
for (const auto& w : word) {
if (root->next[w - 'a'] == nullptr)
root->next[w - 'a'] = new Trie();
root = root->next[w - 'a'];
}
root->isLeaf = true;
}
bool search(const string& word) {
Trie* root = this;
for (const auto& w : word) {
if (root->next[w - 'a'] == nullptr)
return false;
root = root->next[w - 'a'];
}
return root->isLeaf;
}
};