常用算法简记

string转换成int

string str = "123";
int n = atoi(str.c_str());
cout<<n; //123

vector二维排序

vector格式为[[1,3],[2,2],[3,1]],从大到小排序结果为:

sort(vec.begin(), vec.end(), 
[&](const vector<int> &a, const vector<int> &b){
            return a[1]>b[1];});

判断a字符串是否包含b字符串

判断a字符串是否包含b字符串
if(a.find(b)!=string::npos){
	cout<<"yes"<<endl;
}else{
	cout<<"no"<<endl;

一次遍历找第二大的数

int max1 = -1int max2 = -1for(auto x : vec){
	
	if(x > max1){
        max2 = max1;
        max1 = x;	
	}
    else if(x>max2 && x<max1)
    {
    	max2 = x;}
return max2;

二分

1. 左闭右开
int search(vector<int>& nums, int target) {
        int left = 0;
        // 定义target在左闭右开的区间里,即:[left, right)
        int right = nums.size(); 
        //因为left==right的时候,在[left,right)是无效
        //的空间,所以使用<
        while (left < right) { 
            int middle = left + ((right - left) >> 1);
            if (nums[middle] > target) {
            // target 在左区间,在[left, middle)中
                right = middle; 
            } else if (nums[middle] < target) {
            // target 在右区间,在[middle + 1, right)中
                left = middle + 1; 
            } else { // nums[middle] == target
                return middle;
            }
        }
        // 未找到目标值
        return -1;
    }
2. 左闭右闭
int search(vector<int>& nums, int target) {
       int left = 0;
       //定义target在左闭右闭的区间里,[left, right]
       int right = nums.size() - 1; 
       //当left==right,区间[left,right]依然有效,所以用<=
       while (left <= right) { 
           // 防止溢出 等同于(left + right)/2
           int middle = left + ((right - left) / 2);
           if (nums[middle] > target) {
               // target 在左区间,所以[left, middle-1]
               right = middle - 1; 
           } else if (nums[middle] < target) {
               // target 在右区间,所以[middle+1,right]
               left = middle + 1; 
           } else { // nums[middle] == target
           		// 数组中找到目标值,直接返回下标
               return middle; 
           }
        }
        // 未找到目标值
       return -1;
    }

二叉树

如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值
如果要搜索其中一条符合条件的路径,那么递归需要返回值
if (递归函数(root->left)) return ;

if (递归函数(root->right)) return ;
如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值
left = 递归函数(root->left);
right = 递归函数(root->right);
left与right的逻辑处理;

遍历map

//方法一
for(auto i=map.begin();i!=map.end();i++){}
//方法二
for(auto& [_, v] : map)//(遍历value)
for(auto& [k, v] : map)//(遍历key,value)

map对value排序

vector<pair<int, int>> vec;
for (auto i = map.begin(); i != map.end(); i++)
    vec.push_back(make_pair(i->first, i->second));

sort(vec.begin(), vec.end(), 
    [](const pair<int, int> &x, 
    const pair<int, int> &y) 
    -> int {
    return x.second < y.second;
});
    

移除k个数,使数字最小

k次扫描,找第一个比后面大的字符删除
可以使用栈或者二重循环

判断两数是否互质(最大公因数为1)

if (gcd(i, j) != 1) 
	continue;不互质则跳过

判断质数

 bool isPrime(int n)
    {
        if(n==1)
            return false;
        if(n<=3)
            return true;
        int i;
        for(i=2;i<=sqrt(n);i++)
            if(n%i==0)
                break;
        if(i>sqrt(n))
            return true;
        return false;
    }

优先级队列

小顶堆
priority_queue <int,vector<int>,greater<int> > q;
大顶堆
priority_queue <int,vector<int> > q;

回溯带有判断条件

//right
for(int i = index; i <= n; i++){
	if(A){
		push_back();
		dfs()
		pop_back();
	}
	if(B){
		push_back();
		dfs()
		pop_back();
	}
}
//error
for(int i = index; i <= n; i++){
	if(A)
		push_back();
	if(B)
		push_back();
	dfs()
	if(A)
		pop_back();
	if(B)
		pop_back();
}

组合问题(每个元素在每个组合中只能使用一次)

for循环每次从startIndex开始遍历,下一层搜索要从i+1开始

void backtracking(int n, int k, int startIndex){
	if(终止条件){}
	for (int i = startIndex; i < n; i++){
		backtracking(n, k, i + 1);//回溯
	}
}

组合总和(每个元素都可以无限制重复被选取)

for循环每次从startIndex开始遍历,下一层搜索仍然为i,不用i+1了,表示可以重复读取当前的数

void backtracking(int n, int k, int startIndex){
	if(终止条件){}
	for (int i = startIndex; i < n; i++){
		backtracking(n, k, i);//回溯
	}
}

组合总和2(每个元素在每个组合中只能使用一次,但集合包含重复元素)

集合有重复元素,但还不能有重复的组合
要对同一树层使用过的元素进行跳过

if (i>0 && nums[i]==nums[i-1] && used[i-1]==false) 
{
	continue;
}

全排列

排列问题,每次都要从头开始搜索,要从0开始而不是startIndex。
因此也需要记录哪些元素已经被使用

 for (int i = 0; i < nums.size(); i++) {
 		// path里已经收录的元素,直接跳过
        if (used[i] == true) 
        	continue; 
        used[i] = true;
        path.push_back(nums[i]);
        backtracking(nums, used);
        path.pop_back();
        used[i] = false;
}

全排列 II(集合包含重复元素,去重)

要对同一树层使用过的元素进行跳过

//加在for循环中
if (i>0 && nums[i]==nums[i-1] && used[i-1]==false) 
{
	continue;
}

进制转换

将一个十进制数,转换为N进制数,通用公式:就是用该十进制数对N取模,并令该十进制数等于该数对N取余的结果。结果取反后即为答案

求多个区间的最大重合数量

会议室2
会议室2,可输出区间
生存人数:在会议室的基础上记录下标

检测循环依赖,拓扑排序

选择图中一个入度为0的点,记录下来
在图中删除该点和所有以它为起点的边
重复1和2,直到图为空或没有入度为0的点。

并查集

递归算法的时间复杂度

时间复杂度:递归的总次数*每次递归的数量
空间复杂度:递归的深度*每次递归创建变量的个数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值