【
在桌子上有 N 张卡片,每张卡片的正面和背面都写着一个正数(正面与背面上的数有可能不一样)。
我们可以先翻转任意张卡片,然后选择其中一张卡片。
如果选中的那张卡片背面的数字 X 与任意一张卡片的正面的数字都不同,那么这个数字是我们想要的数字。
哪个数是这些想要的数字中最小的数(找到这些数中的最小值)呢?如果没有一个数字符合要求的,输出 0。
其中, fronts[i] 和 backs[i] 分别代表第 i 张卡片的正面和背面的数字。
如果我们通过翻转卡片来交换正面与背面上的数,那么当初在正面的数就变成背面的数,背面的数就变成正面的数。
示例:
输入:fronts = [1,2,4,4,7], backs = [1,3,4,1,3]
输出:2
解释:假设我们翻转第二张卡片,那么在正面的数变成了 [1,3,4,4,7] , 背面的数变成了 [1,2,4,1,3]。
接着我们选择第二张卡片,因为现在该卡片的背面的数是 2,2 与任意卡片上正面的数都不同,所以 2 就是我们想要的数字。
提示:
1 <= fronts.length == backs.length <= 1000
1 <= fronts[i] <= 2000
1 <= backs[i] <= 2000
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/card-flipping-game
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
】
1)明确一个重要观念,双面一致的数字一定不是我们想要的数字
2)与上面相似但需要理解的,只要这个数字没有出现过双面一致,就是我们想要的数字之一
例子: //第一点很好理解,重点是第二点
1 2 7 3 2 2
1 3 2 2 6 3
把握住1已经不能取,2没有出现过双面一致
我们就可以想办法调换,把2全部盖在下面
1 3 7 3 6 3
1 2 2 2 2 2//这就实现了2最小
其他同理,只要不是双面一致,就能取到
注意点:
1. noselarr 可以排升序,如果x < noselarr[i],肯定不会有相等的,返回0
2. qsort 可以值排序前n个数
方法一如下:先找出哪些数字不能选,放入一个数组,然后遍历,把正面和反面可选择的放入一个数组,排序后最小的便是所需。
/*方法一 :三个for循环,两个qsort */
int Cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int Innosel(int x, int *noselarr, int size)
{
int i;
for (i = 0; i < size; i++) {
if (x == noselarr[i]) {
return 1;
} else if (x < noselarr[i]) {
return 0;
}
}
return 0;
}
int flipgame(int* fronts, int frontsSize, int* backs, int backsSize){
int i;
int min = INT_MAX;
int *noselarr = malloc(sizeof(int) * frontsSize);
int noidx = 0;
int selarr[frontsSize * 2];
int sidx = 0;
memset(noselarr, 0, sizeof(int) * frontsSize);
for (i = 0; i < frontsSize * 2; i++) {
selarr[i] = INT_MAX;
}
for (i = 0; i < frontsSize; i++) {
if (fronts[i] == backs[i]) {
noselarr[noidx++] = fronts[i];
}
}
qsort(noselarr, noidx, sizeof(int), Cmp);
for (i = 0; i < frontsSize; i++) {
if (Innosel(fronts[i], noselarr, frontsSize) == 0) {
selarr[sidx++] = fronts[i];
}
if (Innosel(backs[i], noselarr, frontsSize) == 0) {
selarr[sidx++] = backs[i];
}
}
if (sidx == 0) {
return 0;
}
qsort(selarr, sidx, sizeof(int), Cmp);
return selarr[0];
}
方法二:
我们发现最大值只有2000,那么可以用哈希,代码会更少些
/* 方法二: */
int flipgame(int* fronts, int frontsSize, int* backs, int backsSize){
int i;
int hash[2001] = {0}; // 最大值只有 2000
for (i = 0; i < frontsSize; i++) {
if (fronts[i] == backs[i]) { // 正反面相等赋值为 -1,不可能是返回值
hash[fronts[i]] = -1;
continue;
}
if (hash[fronts[i]] == 0) { // 如果这个数之前没出现过,那么赋值1表示已经出现了
hash[fronts[i]] = 1;
}
if (hash[backs[i]] == 0) { // 反面数也需要考虑
hash[backs[i]] = 1;
}
}
for (i = 0; i < 2001; i++) { // 遍历已出现过的数,如果存在就是这个数了
if (hash[i] == 1) {
return i;
}
}
return 0;
}