diff --git a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/README.md b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/README.md index 74a6cdfa5c55a..cd8a3798f3ea0 100644 --- a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/README.md +++ b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/README.md @@ -48,6 +48,18 @@ +**方法一:贪心** + +根据题目描述,我们知道,要使得 $tops$ 中所有值或者 $bottoms$ 中所有值都相同,那么这个值必须是 $tops[0]$ 或者 $bottoms[0]$ 中的一个。 + +因此,我们设计一个函数 $f(x)$,表示将所有的值都变成 $x$ 的最小旋转次数,那么答案就是 $\min\{f(\textit{tops}[0]), f(\textit{bottoms}[0])\}$。 + +函数 $f(x)$ 的计算方法如下: + +我们用两个变量 $cnt1$ 和 $cnt2$ 统计 $tops$ 和 $bottoms$ 中等于 $x$ 的个数,用 $n$ 减去它们的最大值,就是将所有值都变成 $x$ 的最小旋转次数。注意,如果 $tops$ 和 $bottoms$ 中没有等于 $x$ 的值,那么 $f(x)$ 的值就是一个很大的数,我们用 $n + 1$ 表示这个数。 + +时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$。 + ### **Python3** @@ -55,7 +67,19 @@ ```python - +class Solution: + def minDominoRotations(self, tops: List[int], bottoms: List[int]) -> int: + def f(x: int) -> int: + cnt1 = cnt2 = 0 + for a, b in zip(tops, bottoms): + if x not in (a, b): + return inf + cnt1 += a == x + cnt2 += b == x + return len(tops) - max(cnt1, cnt2) + + ans = min(f(tops[0]), f(bottoms[0])) + return -1 if ans == inf else ans ``` ### **Java** @@ -63,7 +87,119 @@ ```java +class Solution { + private int n; + private int[] tops; + private int[] bottoms; + + public int minDominoRotations(int[] tops, int[] bottoms) { + n = tops.length; + this.tops = tops; + this.bottoms = bottoms; + int ans = Math.min(f(tops[0]), f(bottoms[0])); + return ans > n ? -1 : ans; + } + + private int f(int x) { + int cnt1 = 0, cnt2 = 0; + for (int i = 0; i < n; ++i) { + if (tops[i] != x && bottoms[i] != x) { + return n + 1; + } + cnt1 += tops[i] == x ? 1 : 0; + cnt2 += bottoms[i] == x ? 1 : 0; + } + return n - Math.max(cnt1, cnt2); + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minDominoRotations(vector& tops, vector& bottoms) { + int n = tops.size(); + auto f = [&](int x) { + int cnt1 = 0, cnt2 = 0; + for (int i = 0; i < n; ++i) { + if (tops[i] != x && bottoms[i] != x) { + return n + 1; + } + cnt1 += tops[i] == x; + cnt2 += bottoms[i] == x; + } + return n - max(cnt1, cnt2); + }; + int ans = min(f(tops[0]), f(bottoms[0])); + return ans > n ? -1 : ans; + } +}; +``` + +### **Go** + +```go +func minDominoRotations(tops []int, bottoms []int) int { + n := len(tops) + f := func(x int) int { + cnt1, cnt2 := 0, 0 + for i, a := range tops { + b := bottoms[i] + if a != x && b != x { + return n + 1 + } + if a == x { + cnt1++ + } + if b == x { + cnt2++ + } + } + return n - max(cnt1, cnt2) + } + ans := min(f(tops[0]), f(bottoms[0])) + if ans > n { + return -1 + } + return ans +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} +``` +### **TypeScript** + +```ts +function minDominoRotations(tops: number[], bottoms: number[]): number { + const n = tops.length; + const f = (x: number): number => { + let [cnt1, cnt2] = [0, 0]; + for (let i = 0; i < n; ++i) { + if (tops[i] !== x && bottoms[i] !== x) { + return n + 1; + } + cnt1 += tops[i] === x ? 1 : 0; + cnt2 += bottoms[i] === x ? 1 : 0; + } + return n - Math.max(cnt1, cnt2); + }; + const ans = Math.min(f(tops[0]), f(bottoms[0])); + return ans > n ? -1 : ans; +} ``` ### **...** diff --git a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/README_EN.md b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/README_EN.md index ff77387f33950..4cff1db5a20fd 100644 --- a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/README_EN.md +++ b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/README_EN.md @@ -43,18 +43,154 @@ In this case, it is not possible to rotate the dominoes to make one row of value ## Solutions +**Solution 1: Greedy** + +According to the problem description, we know that in order to make all values in $tops$ or all values in $bottoms$ the same, the value must be one of $tops[0]$ or $bottoms[0]$. + +Therefore, we design a function $f(x)$ to represent the minimum number of rotations required to make all values equal to $x$. Then the answer is $\min\{f(\textit{tops}[0]), f(\textit{bottoms}[0])\}$. + +The calculation method of function $f(x)$ is as follows: + +We use two variables $cnt1$ and $cnt2$ to count the number of occurrences of $x$ in $tops$ and $bottoms$, respectively. We subtract the maximum value of $cnt1$ and $cnt2$ from $n$, which is the minimum number of rotations required to make all values equal to $x$. Note that if there are no values equal to $x$ in $tops$ and $bottoms$, the value of $f(x)$ is a very large number, which we represent as $n+1$. + +The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$. + ### **Python3** ```python - +class Solution: + def minDominoRotations(self, tops: List[int], bottoms: List[int]) -> int: + def f(x: int) -> int: + cnt1 = cnt2 = 0 + for a, b in zip(tops, bottoms): + if x not in (a, b): + return inf + cnt1 += a == x + cnt2 += b == x + return len(tops) - max(cnt1, cnt2) + + ans = min(f(tops[0]), f(bottoms[0])) + return -1 if ans == inf else ans ``` ### **Java** ```java +class Solution { + private int n; + private int[] tops; + private int[] bottoms; + + public int minDominoRotations(int[] tops, int[] bottoms) { + n = tops.length; + this.tops = tops; + this.bottoms = bottoms; + int ans = Math.min(f(tops[0]), f(bottoms[0])); + return ans > n ? -1 : ans; + } + + private int f(int x) { + int cnt1 = 0, cnt2 = 0; + for (int i = 0; i < n; ++i) { + if (tops[i] != x && bottoms[i] != x) { + return n + 1; + } + cnt1 += tops[i] == x ? 1 : 0; + cnt2 += bottoms[i] == x ? 1 : 0; + } + return n - Math.max(cnt1, cnt2); + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minDominoRotations(vector& tops, vector& bottoms) { + int n = tops.size(); + auto f = [&](int x) { + int cnt1 = 0, cnt2 = 0; + for (int i = 0; i < n; ++i) { + if (tops[i] != x && bottoms[i] != x) { + return n + 1; + } + cnt1 += tops[i] == x; + cnt2 += bottoms[i] == x; + } + return n - max(cnt1, cnt2); + }; + int ans = min(f(tops[0]), f(bottoms[0])); + return ans > n ? -1 : ans; + } +}; +``` + +### **Go** + +```go +func minDominoRotations(tops []int, bottoms []int) int { + n := len(tops) + f := func(x int) int { + cnt1, cnt2 := 0, 0 + for i, a := range tops { + b := bottoms[i] + if a != x && b != x { + return n + 1 + } + if a == x { + cnt1++ + } + if b == x { + cnt2++ + } + } + return n - max(cnt1, cnt2) + } + ans := min(f(tops[0]), f(bottoms[0])) + if ans > n { + return -1 + } + return ans +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} +``` +### **TypeScript** + +```ts +function minDominoRotations(tops: number[], bottoms: number[]): number { + const n = tops.length; + const f = (x: number): number => { + let [cnt1, cnt2] = [0, 0]; + for (let i = 0; i < n; ++i) { + if (tops[i] !== x && bottoms[i] !== x) { + return n + 1; + } + cnt1 += tops[i] === x ? 1 : 0; + cnt2 += bottoms[i] === x ? 1 : 0; + } + return n - Math.max(cnt1, cnt2); + }; + const ans = Math.min(f(tops[0]), f(bottoms[0])); + return ans > n ? -1 : ans; +} ``` ### **...** diff --git a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.cpp b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.cpp new file mode 100644 index 0000000000000..7e2a2b35772c1 --- /dev/null +++ b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.cpp @@ -0,0 +1,19 @@ +class Solution { +public: + int minDominoRotations(vector& tops, vector& bottoms) { + int n = tops.size(); + auto f = [&](int x) { + int cnt1 = 0, cnt2 = 0; + for (int i = 0; i < n; ++i) { + if (tops[i] != x && bottoms[i] != x) { + return n + 1; + } + cnt1 += tops[i] == x; + cnt2 += bottoms[i] == x; + } + return n - max(cnt1, cnt2); + }; + int ans = min(f(tops[0]), f(bottoms[0])); + return ans > n ? -1 : ans; + } +}; \ No newline at end of file diff --git a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.go b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.go new file mode 100644 index 0000000000000..76f173bc8134e --- /dev/null +++ b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.go @@ -0,0 +1,38 @@ +func minDominoRotations(tops []int, bottoms []int) int { + n := len(tops) + f := func(x int) int { + cnt1, cnt2 := 0, 0 + for i, a := range tops { + b := bottoms[i] + if a != x && b != x { + return n + 1 + } + if a == x { + cnt1++ + } + if b == x { + cnt2++ + } + } + return n - max(cnt1, cnt2) + } + ans := min(f(tops[0]), f(bottoms[0])) + if ans > n { + return -1 + } + return ans +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} \ No newline at end of file diff --git a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.java b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.java new file mode 100644 index 0000000000000..02ed69d229769 --- /dev/null +++ b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.java @@ -0,0 +1,25 @@ +class Solution { + private int n; + private int[] tops; + private int[] bottoms; + + public int minDominoRotations(int[] tops, int[] bottoms) { + n = tops.length; + this.tops = tops; + this.bottoms = bottoms; + int ans = Math.min(f(tops[0]), f(bottoms[0])); + return ans > n ? -1 : ans; + } + + private int f(int x) { + int cnt1 = 0, cnt2 = 0; + for (int i = 0; i < n; ++i) { + if (tops[i] != x && bottoms[i] != x) { + return n + 1; + } + cnt1 += tops[i] == x ? 1 : 0; + cnt2 += bottoms[i] == x ? 1 : 0; + } + return n - Math.max(cnt1, cnt2); + } +} \ No newline at end of file diff --git a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.py b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.py index b4613fa641501..ca4aef26d605a 100644 --- a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.py +++ b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.py @@ -1,39 +1,13 @@ class Solution: - def minDominoRotations(self, A: List[int], B: List[int]) -> int: - a, b = A[0], B[0] - c, d = b, a - counta, countb = 0, 0 - countc, countd = 1, 1 - for ai, bi in zip(A[1:], B[1:]): - if ai == a: - pass - elif ai != a and bi == a: - counta += 1 - else: - counta = -30000 - if bi == b: - pass - elif bi != b and ai == b: - countb += 1 - else: - countb = -30000 - if ai == c: - pass - elif ai != c and bi == c: - countc += 1 - else: - countc = -30000 - if bi == d: - pass - elif bi != d and ai == d: - countd += 1 - else: - countd = -30000 - if counta < 0 and countb < 0 and countc < 0 and countd < 0: - return -1 - else: - ans = 30000 - for count in [counta, countb, countc, countd]: - if count >= 0: - ans = min(ans, count) - return ans + def minDominoRotations(self, tops: List[int], bottoms: List[int]) -> int: + def f(x: int) -> int: + cnt1 = cnt2 = 0 + for a, b in zip(tops, bottoms): + if x not in (a, b): + return inf + cnt1 += a == x + cnt2 += b == x + return len(tops) - max(cnt1, cnt2) + + ans = min(f(tops[0]), f(bottoms[0])) + return -1 if ans == inf else ans diff --git a/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.ts b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.ts new file mode 100644 index 0000000000000..557001c89d2ce --- /dev/null +++ b/solution/1000-1099/1007.Minimum Domino Rotations For Equal Row/Solution.ts @@ -0,0 +1,16 @@ +function minDominoRotations(tops: number[], bottoms: number[]): number { + const n = tops.length; + const f = (x: number): number => { + let [cnt1, cnt2] = [0, 0]; + for (let i = 0; i < n; ++i) { + if (tops[i] !== x && bottoms[i] !== x) { + return n + 1; + } + cnt1 += tops[i] === x ? 1 : 0; + cnt2 += bottoms[i] === x ? 1 : 0; + } + return n - Math.max(cnt1, cnt2); + }; + const ans = Math.min(f(tops[0]), f(bottoms[0])); + return ans > n ? -1 : ans; +}