题目描述
思路解析动画文字版
记住这套「候选只有第 0 列的两个数 → 对每个候选扫一遍数翻转」,下面每帧都在套它。
先看第 0 列:上是 2、下是 5。整行要统一成 x,第 0 列必须出得了 x,所以 x 只能是 2 或 5。我们先试 x = 2。
开扫候选 x=2:用 top 记「想统一上行需翻几张」,bottom 记「想统一下行需翻几张」,两个都从 0 开始。
看第 0 列:上 2、下 5。只要上或下里有一个是 2,这列就有救。
第 0 列:上是 2、下是 5:上行不用翻;若想让下行变 2,这列得翻一张(bottom+1)。 累计 top=0、bottom=1。
看第 1 列:上 1、下 2。只要上或下里有一个是 2,这列就有救。
第 1 列:上是 1(不是 2),但下是 2:若想让上行变 2,这列得翻一张(top+1);下行本就是 2,下行不用翻。 累计 top=1、bottom=1。
看第 2 列:上 2、下 6。只要上或下里有一个是 2,这列就有救。
第 2 列:上是 2、下是 6:上行不用翻;若想让下行变 2,这列得翻一张(bottom+1)。 累计 top=1、bottom=2。
看第 3 列:上 4、下 2。只要上或下里有一个是 2,这列就有救。
第 3 列:上是 4(不是 2),但下是 2:若想让上行变 2,这列得翻一张(top+1);下行本就是 2,下行不用翻。 累计 top=2、bottom=2。
看第 4 列:上 2、下 3。只要上或下里有一个是 2,这列就有救。
第 4 列:上是 2、下是 3:上行不用翻;若想让下行变 2,这列得翻一张(bottom+1)。 累计 top=2、bottom=3。
看第 5 列:上 2、下 2。只要上或下里有一个是 2,这列就有救。
第 5 列:上下都是 2,怎么放都行,两边都不用翻。 累计 top=2、bottom=3。
候选 x=2 全列都过关。凑上行要翻 2 张、凑下行要翻 3 张,取较小的 → 2 张。这就是 x=2 的代价。
别忘了还有第二个候选:把整行统一成下行第 0 个的值 x=5。计数器清零,从第 0 列重新扫。
候选 5:看第 0 列,上 2、下 5。这一列里有没有 5?
第 0 列有 5,本列过关。累计 top=1、bottom=0。
候选 5:看第 1 列,上 1、下 2。这一列里有没有 5?
第 1 列上 1、下 2,两个都不是 5:无论翻不翻,这列都出不来 5。候选 5 当场出局(红色那列卡死)。
两个候选里:x=2 要 2 张,x=5 出局。取能成的最小值 → 答案 2。若两个候选都出局,则返回 -1。
边界先想清:单列与已相同都是 0;没有候选能盖住全列才是 -1。
两个高频追问:必须试两个候选;极大值是为了统一参与 min。
参考代码
from typing import Listclass Solution: def minDominoRotations(self, tops: List[int], bottoms: List[int]) -> int: def check(x): top = bottom = 0 for a, b in zip(tops, bottoms): if a != x and b != x: return 10**9 if a != x: top += 1 if b != x: bottom += 1 return min(top, bottom) ans = min(check(tops[0]), check(bottoms[0])) return -1 if ans == 10**9 else ans复杂度
- 时间:O(n),最多两个候选,每个扫一遍 n 列,共 2n
- 空间:O(1),只用 top、bottom 几个计数器
易错点
面试追问把动画讲成自己的话
追问如果只试 tops[0] 一个候选,会漏答案吗?
追问为什么用「极大值」当无解标记,而不是直接 return -1?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
两地调度
LeetCode 1029 · 中等 · 沿着 贪心套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题