有很多的基礎算法經常會用到,但是又容易寫錯。而網上查到的實現又五花八門、良莠不齊,故在此整理記錄。
本文的目錄如下:
1.二分查找 2.並查集
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
};