常用算法模板

我因为做题的时候经常忘掉某一部分模板,所以经过惨烈的教训,把它贴在这,忘了就来看这个。
二分模板:

int binary(int l, int r) {
    int L = l, R = r, M = 0;
    while(L < R) {
        M = L + R >> 1;
        if(check()) R = M;
        else L = M + 1;
    }
    return R;
} 

C++标准库中

    int nums[] = {1,2,3,4,5,6,7};
    bool fg = binary_search(nums, nums+7, 4); // STL中的二分查找返回bool类型
    // lower_bound : 找到大于等于的值
    int k = lower_bound(nums, nums+7, 4) - nums; // 用lower_bound 减去第一个元素地址表示找到值是在第几个位置;
    // output: k = 3;
    // ** 注意:没有找到返回 元素个数(7), 有迭代器返回迭代器; 迭代器与指针类似
    int *addk = lower_bound(nums, nums+7, 4); // 得到地址
    // upper_bound:找到大于的值。 用法与lower_bound相同

快速查找:
algorithm头文件中有:
count(st,ed,elem) – 找到等于elem的个数
max_element(st,ed,elem) – 找到最大的元素的地址
min_element(st,ed,elem) – 同上

排序:
sort默认从小到大排,用仿函数可以从大到小排
greater< int>() :从大到小排
如何去重:
vi.erase(unique

倒序:
reverse(st,ed)

排列组合:
在stl中有一个全排列的算法:**next_permutation(st,ed);
使用方法:

    int nums[] = {1,2,3,4,5,6,7};
    do { // 查找完后,自动结束
        for(int i = 0; i < 7; ++i) cout<<nums[i]<<" "; puts("");
    } while(next_permutation(nums, nums+7));

如何用它来模拟组合?
可以用另一个数组,将部分赋值为其他值,进行判断;

   bool nums[7];
   for(int i = 4; i < 7; ++i) nums[i] = 1; // true;
    do {
        for(int i = 0; i < 4; ++i) cout<<nums[i]<<" "; puts("");
    } while(next_permutation(nums, nums+7));

这个程序,打印的都是0 1; 打印其他也可以;
只需要再添加一个数组。

   bool nums[7];
   int mus[] = {1,2,3,4,5,6,7};
   // 本质是:打印nums的全排列
   for(int i = 4; i < 7; ++i) nums[i] = 1; // true;
		// 这是打印4个数的组合
    do {
        for(int i = 0; i < 7; ++i) { // NOTICE: i < 7;
        // 判断是否nums为0, 为零输出musi[i];
            if(nums[i] == 0) cout<<mus[i]<<" ";
        } 
        puts("");
    } while(next_permutation(nums, nums+7));

判断质数:

质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
用试除法判断质数:

bool isPrime(int x) {
    if(x < 2) return false;
    for(int i = 2; i <= x/i; ++i) 
        if(x%i == 0) return false;

    return true;
}

最大公约数:

两个或多个整数共有约数中最大的一个

int gcd(int a, int b) {
    return b?gcd(b, a%b):a;
}
 // __gcd(a,b); 内置

大顶堆,小顶堆:
用prority_queue 优先队列实现:
prority_queue< int> pq; // 大顶堆。
prority_queue< int, vector< int>, greater< int>> spq; // 小顶堆

区间求和:

vector<pair<int,int>> RangeSum(vector<pair<int,int>> &a) {
    vector<pair<int,int>> la;
    sort(a.begin(), a.end());
    int len = a.size();
    la.push_back(a[0]);
    for(int i = 1; i < len; ++i) {
        if(a[i].first <= la.back().second) la.back().second = max(la.back().second, a[i].second);
        else la.push_back(a[i]);
    }
    return la;
}

哈希:
可用C++11的 unordered_map或map

快速开拓思路的想法:看样例,排个序,看大小,算差值。想之前做的题,套改经典题。

另外,记得看数据大小,常用LL,根据数据大小,采用合理复杂度,有些题可以根据复杂度想到相近的算法或模型。

你可能感兴趣的:(My学习之路,算法,c++,数据结构)