在一排多米诺骨牌中,tops[i]
和 bottoms[i]
分别代表第 i
个多米诺骨牌的上半部分和下半部分。(一个多米诺是两个从 1 到 6 的数字同列平铺形成的 —— 该平铺的每一半上都有一个数字。)
我们可以旋转第 i
张多米诺,使得 tops[i]
和 bottoms[i]
的值交换。
返回能使 tops
中所有值或者 bottoms
中所有值都相同的最小旋转次数。
如果无法做到,返回 -1
.
思考!显然所有情况只会有四种:
①以tops[0]为首,bottoms中和其相等的全部翻转上来,记录次数,如果有一个存在上下都没有,则此次记录作废
②以bottoms[0]为首,tops中和其相等的全部翻转下来,记录次数,如果有一个存在上下都没有,则此次记录作废
③先将top[0]交换到下面,然后重复上面操作
④先将bottoms[0]交换到上面,然后重复上述操作。
实现:
C++:
class Solution {
public:
int Rotations(vector<int>& tops,vector<int>& bottoms,int target){
int toUp = 0;
int toBottom=0;
for(int i = 0;i<tops.size();i++){
int x = tops[i];
int y = bottoms[i];
if(x!=target&&y!=target){
return INT_MAX;
}
if(x!=target){
//上面的不满足条件
//那么下面的一定满足条件 不然在上面就会返回一个最大值了
toUp++;
}else if(y!=target){
toBottom++;
}
}
return min(toUp,toBottom);
}
int minDominoRotations(vector<int>& tops, vector<int>& bottoms) {
int ans = min(Rotations(tops,bottoms,tops[0]),Rotations(tops,bottoms,bottoms[0]));
return ans ==INT_MAX?-1:ans;
}
};
C#:
public class Solution {
//目标函数 计算翻转次数
//target为目标比较对象
public int Rotations(int[] tops,int[] bottoms,int target){
//翻转次数(从上往下)
int topToButtom = 0;
//翻转次数(从下往上)
int buttomToTop = 0;
for(int i = 0;i<tops.Length;i++){
//拿出来比较
int x = tops[i];
int y = bottoms[i];
if(x!=target&&y!=target){
return int.MaxValue;
}
if(x!=target){
buttomToTop++;
}else if(y!=target){
topToButtom++;
}
}
return Math.Min(buttomToTop,topToButtom);
}
public int MinDominoRotations(int[] tops, int[] bottoms) {
int ans = Math.Min(Rotations(tops,bottoms,tops[0]),Rotations(tops,bottoms,bottoms[0]));
return ans ==int.MaxValue?-1:ans;
}
}
不写函数,直接实现:
C++:
class Solution {
public:
int minDominoRotations(vector<int>& tops, vector<int>& bottoms) {
int ans = INT_MAX;
for (int i = 1; i <= 6; i++) {
int toUp = 0;
int toBottom = 0;
bool isValid = true;
for (int j = 0; j < tops.size(); j++) {
if (tops[j] != i && bottoms[j] != i) {
isValid = false;
break;
}
if (tops[j] != i)
toUp++;
if (bottoms[j] != i)
toBottom++;
}
if (isValid) {
ans = min(toBottom, toUp);
}
}
return ans == INT_MAX ? -1 : ans;
}
};
C#:
public class Solution {
public int MinDominoRotations(int[] tops, int[] bottoms) {
int minRotations = int.MaxValue;
// 遍历所有可能的候选值(1到6)
for (int candidate = 1; candidate <= 6; candidate++) {
int topRotations = 0, bottomRotations = 0;
bool validCandidate = true;
for (int i = 0; i < tops.Length; i++) {
// 检查当前候选值是否存在于当前骨牌的两个面中
if (tops[i] != candidate && bottoms[i] != candidate) {
validCandidate = false;
break;
}
// 计算将tops或bottoms全变为candidate所需的旋转次数
if (tops[i] != candidate) topRotations++;
if (bottoms[i] != candidate) bottomRotations++;
}
if (validCandidate) {
// 取两种目标(tops全为candidate或bottoms全为candidate)的较小值
minRotations = Math.Min(minRotations, Math.Min(topRotations, bottomRotations));
}
}
return minRotations == int.MaxValue ? -1 : minRotations;
}
}