LeetCode 822 Card Flipping Game
题目分析
On a table are
N
cards, with a positive integer printed on the front and back of each card (possibly different).We flip any number of cards, and after we choose one card.
If the number
X
on the back of the chosen card is not on the front of any card, then this number X is good.What is the smallest number that is good? If no number is good, output
0
.Here,
fronts[i]
andbacks[i]
represent the number on the front and back of cardi
.A flip swaps the front and back numbers, so the value on the front is now on the back and vice versa.
Example:
Input: fronts = [1,2,4,4,7], backs = [1,3,4,1,3] Output: 2 Explanation: If we flip the second card, the fronts are [1,3,4,4,7] and the backs are [1,2,4,1,3]. We choose the second card, which has number 2 on the back, and it isn't on the front of any card, so 2 is good.
Note:
1 <= fronts.length == backs.length <= 1000.
1 <= fronts[i] <= 2000
.1 <= backs[i] <= 2000
.
这个题的题目很具有迷惑性,首先是将卡片选取任意张进行翻转,再随机选取一张,如果这张卡片的的背面数字x
没有在所有的正面数字中出现,那么这个数字x
就是good的,这个题目要求的是求取最小的满足good条件的数字。
思考
题目看似很复杂,其实只要分析什么样的数字不可能符合就可以很快想到思路了。
首先这个数字不能在卡片的正面出现,如果出现了的话那就不可能是这个数字,那么思考什么要的数字不可能出现呢?在同一张卡片正反两面都出现的数字不可能,如果一个数字在一张卡片的两侧,那么它一定会出现在正面,这个关系明白了就知道了解题思路了,使用一个数组记录数字是否出现,一个数组记录数字是否可能,如果一个数字在所有卡片上都没有出现,那么我们也是不可以选择它的。找出出现了的并且可能的最小数字即可。
程序涉及两次遍历,时间复杂度 O ( n ) O(n) O(n)。
代码实现
class Solution {
public:
int flipgame(vector<int> &fronts, vector<int> &backs) {
int result = 0;
int card_cnt = fronts.size();
// 0 possible
// 1 immpossible
int possible[2001] = {0};
// 0 no, 1 have
int have[2001] = {0};
// 找到所有出现的数字和不可能的数字
for (int i = 0; i < card_cnt; ++i) {
// 标记数字存在
have[fronts[i]] = have[backs[i]] = 1;
if (fronts[i] == backs[i]) {
// fronts[i]必定存在正反面
// 记录为不可能
possible[fronts[i]] = 1;
}
}
for (int i = 1; i < 2001; ++i) {
// 第一个满足条件的数字就是最小的
if (possible[i] == 0 && have[i] == 1) {
return i;
}
}
// 没有满足需求的
return 0;
}
};
感想
仔细分析题意,找出隐含的条件,顺利写出代码。