坑点注意:x不能与任意一张卡片的正面数字相同,包括自己。因此如果一张卡片正反面数字相同,必然不可能是x。
暴力
由于\(n \leq 1000\),因此\(n^2\)暴力是可以过的。遍历每一个\(nums[i]\),判断其正反面是否相同,相同则跳过,不相同则进一步检验。分为两种情况,一是取\(fronts[i]\),另一种是取\(backs[i]\)。检验其他卡片是否至少有一面不同,如果没有,则不能选为x。如果通过,则与答案取一个min。
集合
建立一个set,事先遍历所有的\(nums[i]\),将所有正反面相同的卡片加入到set中。
正反面相同的卡片,无论如何翻转,都不会改变。而正反面不同的卡片,如果一面数字相同了,我们可以翻转到另一面。
- 取卡片的正面的情况。遍历所有卡片,判断set中是否存在与\(fronts[i]\)相同的key,如果不存在,说明正面没有数字与它相同,可以选为x,更新答案。
- 取卡片的反面的情况。遍历所有卡片,判断set中是否存在与\(backs[i]\)相同的key,如果不存在,说明正面同样也没数字与它相同,可以选为x,更新答案。
假设现在有一个卡片1,其正面值为x,反面值为z。而其他卡片中存在一个卡片2其正面值为x,而反面值为y,那么这个卡片是不会被加入到set中的,也就是说x和y必然是不同的。卡片1取正面值时,可以翻转卡片2得到贡献。卡片1取反面值时,可以翻转卡片2也可以不翻转,都也可以得到贡献。
class Solution {
public:
int flipgame(vector<int>& fronts, vector<int>& backs)
{
int n = fronts.size();
int res = 0x3f3f3f3f;
unordered_set<int> s;
for (int i = 0; i < n; ++i)
{
if (fronts[i] == backs[i]) s.insert(fronts[i]);
}
for (int x : fronts)
{
if (x < res && !s.count(x))
res = x;
}
for (int x : backs)
{
if (x < res && !s.count(x))
res = x;
}
return res == 0x3f3f3f3f ? 0 : res;
}
};
标签:fronts,set,卡片,相同,int,res,2023.8,翻转
From: https://www.cnblogs.com/st0rmKR/p/17602833.html