In the Card Flipping Game problem, you are given two integer arrays, fronts
and backs
, each of length n
. Each index i
represents a card: fronts[i]
is the number on the front of the card, and backs[i]
is the number on the back. You can choose any card and flip it, swapping its front and back numbers.
Your goal is to pick any number that appears on the front or back of any card, such that after possibly flipping any cards, this number does not appear on the front of any card. Among all such numbers, return the minimum possible number. If no such number exists, return 0
.
Constraints:
1 <= fronts.length == backs.length <= 1000
1 <= fronts[i], backs[i] <= 2000
At first glance, it might seem like we need to check all possible combinations of flips, but this would be too slow. If we try to brute-force all flip combinations, the number of possibilities grows exponentially with the number of cards.
However, let's think more carefully. Our goal is to find a number that could end up only on the back sides after flipping — that is, after possibly flipping some cards, this number should not be on the front of any card.
But, if a number appears on both sides of the same card, no matter how we flip that card, that number will always be on the front or back. Therefore, such numbers can never be "hidden" from the front, so we must exclude them.
So, the task becomes: among all numbers that appear on some card (either front or back), what is the smallest number that is not on the front of any card after flipping, and is also not "invalid" (i.e., doesn't appear on both sides of the same card).
This suggests we should identify all invalid numbers first, then look for the smallest valid number that can be hidden from all fronts.
fronts[i] == backs[i]
, add that number to a set of "invalid" numbers. These are numbers that cannot be hidden from the front, regardless of flipping.We use sets for efficient lookups and to avoid duplicates. This approach ensures we only consider valid numbers and ignore those that are impossible to hide from the front.
Example Input: fronts = [1,2,4,4,7]
, backs = [1,3,4,1,3]
class Solution:
def flipgame(self, fronts, backs):
invalid = set()
for f, b in zip(fronts, backs):
if f == b:
invalid.add(f)
candidates = set(fronts) | set(backs)
ans = float('inf')
for x in candidates:
if x not in invalid:
ans = min(ans, x)
return 0 if ans == float('inf') else ans
class Solution {
public:
int flipgame(vector<int>& fronts, vector<int>& backs) {
unordered_set<int> invalid;
for (int i = 0; i < fronts.size(); ++i) {
if (fronts[i] == backs[i]) invalid.insert(fronts[i]);
}
int ans = INT_MAX;
for (int x : fronts) {
if (!invalid.count(x)) ans = min(ans, x);
}
for (int x : backs) {
if (!invalid.count(x)) ans = min(ans, x);
}
return ans == INT_MAX ? 0 : ans;
}
};
class Solution {
public int flipgame(int[] fronts, int[] backs) {
Set<Integer> invalid = new HashSet<>();
for (int i = 0; i < fronts.length; i++) {
if (fronts[i] == backs[i]) invalid.add(fronts[i]);
}
int ans = Integer.MAX_VALUE;
for (int x : fronts) {
if (!invalid.contains(x)) ans = Math.min(ans, x);
}
for (int x : backs) {
if (!invalid.contains(x)) ans = Math.min(ans, x);
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}
var flipgame = function(fronts, backs) {
let invalid = new Set();
for (let i = 0; i < fronts.length; i++) {
if (fronts[i] === backs[i]) invalid.add(fronts[i]);
}
let ans = Infinity;
for (let x of fronts.concat(backs)) {
if (!invalid.has(x)) ans = Math.min(ans, x);
}
return ans === Infinity ? 0 : ans;
};
This efficiency is possible because we avoid simulating all flip combinations and instead use set operations to filter out impossible choices.
The Card Flipping Game problem is elegantly solved by observing that numbers appearing on both sides of the same card can never be "hidden" from the front, regardless of flips. By filtering out these invalid numbers and then finding the smallest candidate number from the remaining numbers, we efficiently achieve the solution in linear time. This approach avoids brute-force and leverages set operations for clarity and speed.