算法笔记刷题笔记思路技巧

一.STL

1.hypot() 求两点间的距离 谨慎使用 太耗时了
用法: res=min(res,hypot(nums[i].x-nums[j].x,nums[i].y-nums[j].y));//太耗时了 不如自己写

2.back() 求vector数组的最后一个元素 若为二维的vector则该元素为 一维数组 back()[1] 表示一维数组的第二个元素
优先队列pq用方法:emplace表示入队一个元素 ,pop()表示删除队头元素,top()表示获取队头元素
vector用方法emplace_back:表示从最后添加一个元素 back()表示获取最后一个元素 pop_back()表示删除最后一个元素

用法:(res.back()[1]>=intervals[i][0])
3.max_element(vector.begin(),vector.end()) 求vector数组的最大元素 注意要加 不然求的是地址

4.accumulate() 求和函数
用法:accumulate(vector.begin(),vector.end(),0) 这个0表示 初始sum设为0
5.lower_bound:返回大于等于目标值的迭代器
例一:

#include
#include
#include
using namespace std;
int main()
{
vector v = { 3, 4, 1, 2, 8 };
// 无序数组,不用sort排序,下面调用lower_bound排序
// 定义两个迭代器变量
vector::iterator iter1;
vector::iterator iter2;
//less() 是建小堆,排升序。
//所以数组 v = {1,2,3,4,8}
//我们找第一个比1大的,那肯定就是首元素1了
//我们找第一个比8大的,没有,所以就指向数组最后一个元素8了
iter1 = lower_bound(v.begin(), v.end(), 1, less());//
iter2 = lower_bound(v.begin(), v.end(), 8, less());//
cout << iter1 - v.begin() << endl; //下标 所以就是 0
cout << iter2 - v.begin() << endl; //下标 所以就是 4
system(“pause”);
}
例二:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;


int main()
{
	vector<int> v = { 3, 4, 1, 2, 8 };
	// 无序数组,不用sort排序,下面调用lower_bound排序

	// 定义两个迭代器变量 
	vector<int>::iterator iter1;
	vector<int>::iterator iter2;

	//less<int>() 是建小堆,排升序。
	//所以数组 v = {1,2,3,4,8} 
	//我们找第一个比1大的,那肯定就是首元素1了
	//我们找第一个比8大的,没有,所以就指向数组最后一个元素8了
	iter1 = lower_bound(v.begin(), v.end(), 1, less<int>());//
	iter2 = lower_bound(v.begin(), v.end(), 8, less<int>());//

	cout << iter1 - v.begin() << endl; //下标 所以就是 0
	cout << iter2 - v.begin() << endl; //下标 所以就是 4
	system("pause");
}

二.注意事项

1.自己最好手写两点间的距离函数
如:double dis(Node &a,Node &b){
return (a.x-b.x)(a.x-b.x)+(a.y-b.y)(a.y-b.y);//在结果加sqrt 可以节约时间
}
注意:在最后的结果才加sqrt可以节约时间

2.下面语句可以四舍五入到保留指定位数

cout<<fixed<<setprecision(4)<<sqrt(solution.minDistance(nums))<<endl;
3.以下两个for循环 是求最近点对的关键 确保每个点都与其他点参与了一次运算 而没有重复计算

for(int i=0;i<nums.size();i++){
            for(int j=i+1;j<nums.size();j++){
                res=min(res,dis(nums[i],nums[j]));
            }
        }

4.对于二维数组的遍历 最好使用for(int num:nums)这种形式 更加方便

for(vector<int> update:updates){
            int i=update[0];
            int j=update[1];
            int val=update[2];
            difference.increment(i,j,val);
        }

5.二维坐标 (x,y) 可以转换成 x * n + y 这个数(m 是棋盘的行数,n 是棋盘的列数),这是将二维坐标映射到一维的常用技巧。
如二维数组 投影到一维数组后 就为:{0,1,2,3}

x 0x 1
x 2x 3

6.在克鲁斯卡尔问题 求最小生成树中 当题中给出的点为 坐标形式(x,y) 没有显示的给出两个点的权重
则我们可以开一个数组 用于放 两个点的信息以及权重 这一步很精妙 如下:

vector<vector<int>> edges;
        UF uf(m);
        int mst=0;
        for(int i=0;i<m;i++){
            for(int j=i+1;j<m;j++){
                int x1=points[i][0],x2=points[i][1];
                int y1=points[j][0],y2=points[j][1];
                //这一步太秀了 好好琢磨
                edges.push_back({i,j,abs(x1-x2)+abs(y1-y2)});
            }
        }

这个 edge数组 就代替了 原题中给出的数组 因为这个数组是标准的三元组 满足我们求最小生成树的需要。

7.关于emplace函数 在vector数组 是这样用的emplace(pos,value) 即必须给出在哪个位置插入元素
而在优先队列priority_queue中 emplace没有pos参数 只有value一个参数
但两者的emplace_back函数是一样的形式

  1. vector<vector> nums(m, vector(2));这样定义二维数组 表示 你要用到nums[i][j],不可以 nums[x].emplace_back(y);
    而vector<vector> nums(1000); 这样定义的话 类似 图的邻接表 你会这样操作 nums[x].emplace_back(y);也可以nums[i][j]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值