代码的奇技淫巧
一
用C++刷题,判断边界测试用例时:
if (nums.size() <= 2) {
return *max_element(nums.begin(), nums.end()); // 注意nums.size()必须不为零!
}
主要是可以简单获取vector的最大值,不用自己去遍历,省事,但要注意如果nums()为空,那max_element返回的是vector.end(),会出现未定义行为,就坏了:
int maxV = *max_element(nums.begin(), nums.end()) // 必须要先保证nums.size()>0 !
3
二
善用优先队列priority_queue、无序集合unordered_set(底层实现是HashMap)等牛x的数据结构:
有一个题,同时需要这俩,我就写在了一起。一起定义比较器。
这里主要记录自定义的结构体作为这些数据结构的元素的使用方法。关于基本数据类型的简单的使用可以参考其他博文。
有时候刷题的数据组成较为复杂,需要自己定义结构体。
但是!在C++中,如果你想在unordered_set中存储自定义类型(如你的node类型),你需要提供一个哈希函数和一个等价函数。哈希函数用于计算每个元素的哈希值,等价函数用于比较两个元素是否相等。
这是因为unordered_set是一个哈希表,它需要这两个函数来确定元素在哈希表中的位置,并确保所有元素都是唯一的。
如果你没有提供这两个函数,编译器就会尝试使用默认的std::hash和std::equal_to,但是这两个模板在STL标准库中并没有为自定义类型提供特化版本,所以会导致编译错误。
解决这个问题的方法是为你的咱们的自定义类型提供一个哈希函数和一个等价函数。你可以通过特化std::hash和重载operator==来实现。以下是一个示例:
(同样的,如果你想在priority_queue存储node,那也需要提供比较器,不然它不知道哪个node是优先的,就报错。)
class Solution {
public:
struct node { // 每个node有三个数据,记录了开始时间,需要花费的时间,以及小费
node(vector<int> a) {
x = a[0]; // start time
y = a[1]; // spend
z = a[2]; // tip
}
int x;
int y;
int z;
// 下面是unordered_set的等价函数,直接在里面重载operator==
// 也可以写在外面写成一个结构体node_equal,然后在定义set时使用:
// unordered_set<node, node_hash, node_equal> set;
bool operator==(const node& other) const
{
return x == other.x && y == other.y && z == other.z;
}
};
struct node_hash { // unordered_set的哈希函数,自己定义一个计算哈希值的函数,随便定义
size_t operator()(const node& n) const
{
return (((std::hash<int>()(n.y) << 1) ^
std::hash<int>()(n.x) ) >> 1) ^
(std::hash<int>()(n.z) << 1);
}
};
struct cmp2 // 优先队列的比较器,把花费时间从小到大
{
bool operator () (const node &a, const node &b)
{
if (a.y == b.y) return a.x < b.x;
else return a.y < b.y;
}
};
struct cmp1 // 优先队列的比较器,把小费tip从大到小
{
bool operator () (const node &a, const node &b)
{
if (a.z == b.z) return a.x < b.x;
else return a.z > b.z; // 把小费tip从大到小
}
};
vector<int> waiterTip(vector<vector<int>>& customers)
{
priority_queue< node, vector<node>, cmp1> q1;
priority_queue< node, vector<node>, cmp2> q2;
unordered_set<node, node_hash> set;
vector<vector<int> > cus = { {10,20,15},{15,45,20} };
q1.emplace(node(cus[0]));
q2.emplace(node(cus[0]));
set.insert(cus[1])
return vector(2, 0);
}
};