Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion solution/0700-0799/0789.Escape The Ghosts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<p>如果你可以在任何阻碍者抓住你 <strong>之前</strong> 到达目的地(阻碍者可以采取任意行动方式),则被视为逃脱成功。如果你和阻碍者 <strong>同时</strong> 到达了一个位置(包括目的地)&nbsp;<strong>都不算</strong>&nbsp;是逃脱成功。</p>

<p>只有在你有可能成功逃脱时,输出 <code>true</code> ;否则,输出 <code>false</code> 。</p>
<p>如果不管阻碍者怎么移动都可以成功逃脱时,输出 <code>true</code> ;否则,输出 <code>false</code> 。</p>
&nbsp;

<p><strong>示例 1:</strong></p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class Solution:
if s[i] == s[j]:
return dfs(i + 1, j - 1)
return 1 + min(dfs(i + 1, j), dfs(i, j - 1))

return dfs(0, len(s) - 1)
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<p>现在有一个正凸多边形,其上共有 <code>n</code> 个顶点。顶点按顺时针方向从 <code>0</code> 到 <code>n - 1</code> 依次编号。每个顶点上 <strong>正好有一只猴子</strong> 。下图中是一个 6 个顶点的凸多边形。</p>

<p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/2500-2599/2550.Count%20Collisions%20of%20Monkeys%20on%20a%20Polygon/images/hexagon.jpg" style="width: 300px; height: 293px;"></p>
<p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/2500-2599/2550.Count%20Collisions%20of%20Monkeys%20on%20a%20Polygon/images/hexagon.jpg" style="width: 300px; height: 293px;" /></p>

<p>每个猴子同时移动到相邻的顶点。顶点 <code>i</code> 的相邻顶点可以是:</p>

Expand All @@ -17,7 +17,7 @@
<li>逆时针方向的顶点 <code>(i - 1 + n) % n</code> 。</li>
</ul>

<p>如果移动后至少有两个猴子位于同一顶点,则会发生 <strong>碰撞</strong> 。</p>
<p>如果移动后至少有两只猴子停留在同一个顶点上或者相交在一条边上,则会发生 <strong>碰撞</strong> 。</p>

<p>返回猴子至少发生 <strong>一次碰撞 </strong>的移动方法数。由于答案可能非常大,请返回对 <code>10<sup>9</sup>+7</code> 取余后的结果。</p>

Expand All @@ -27,7 +27,8 @@

<p><strong>示例 1:</strong></p>

<pre><strong>输入:</strong>n = 3
<pre>
<strong>输入:</strong>n = 3
<strong>输出:</strong>6
<strong>解释:</strong>共计 8 种移动方式。
下面列出两种会发生碰撞的方式:
Expand All @@ -38,7 +39,8 @@

<p><strong>示例 2:</strong></p>

<pre><strong>输入:</strong>n = 4
<pre>
<strong>输入:</strong>n = 4
<strong>输出:</strong>14
<strong>解释:</strong>可以证明,有 14 种让猴子碰撞的方法。</pre>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,339 @@
# [2605. 从两个数字数组里生成最小数字](https://leetcode.cn/problems/form-smallest-number-from-two-digit-arrays)

[English Version](/solution/2600-2699/2605.Form%20Smallest%20Number%20From%20Two%20Digit%20Arrays/README_EN.md)

## 题目描述

<!-- 这里写题目描述 -->

给你两个只包含 1 到 9 之间数字的数组&nbsp;<code>nums1</code> 和&nbsp;<code>nums2</code>&nbsp;,每个数组中的元素 <strong>互不相同</strong>&nbsp;,请你返回 <strong>最小</strong> 的数字,两个数组都 <strong>至少</strong> 包含这个数字的某个数位。

<p>&nbsp;</p>

<p><strong>示例 1:</strong></p>

<pre><b>输入:</b>nums1 = [4,1,3], nums2 = [5,7]
<b>输出:</b>15
<b>解释:</b>数字 15 的数位 1 在 nums1 中出现,数位 5 在 nums2 中出现。15 是我们能得到的最小数字。
</pre>

<p><strong>示例 2:</strong></p>

<pre><b>输入:</b>nums1 = [3,5,2,6], nums2 = [3,1,7]
<b>输出:</b>3
<b>解释:</b>数字 3 的数位 3 在两个数组中都出现了。
</pre>

<p>&nbsp;</p>

<p><strong>提示:</strong></p>

<ul>
<li><code>1 &lt;= nums1.length, nums2.length &lt;= 9</code></li>
<li><code>1 &lt;= nums1[i], nums2[i] &lt;= 9</code></li>
<li>每个数组中,元素 <strong>互不相同</strong>&nbsp;。</li>
</ul>

## 解法

<!-- 这里可写通用的实现逻辑 -->

**方法一:枚举**

我们观察发现,如果数组 $nums1$ 和 $nums2$ 中有相同的数字,那么相同数字中的最小值一定是最小的数字。否则我们取 $nums1$ 中的数字 $a$ 和 $nums2$ 中的数字 $b$,将 $a$ 和 $b$ 拼接成两个数字,取其中较小的数字即可。

时间复杂度 $O(m \times n)$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别是数组 $nums1$ 和 $nums2$ 的长度。

**方法二:哈希表或数组 + 枚举**

我们可以用哈希表或数组记录数组 $nums1$ 和 $nums2$ 中的数字,然后枚举 $1 \sim 9$,如果 $i$ 在两个数组中都出现了,那么 $i$ 就是最小的数字。否则我们取 $nums1$ 中的数字 $a$ 和 $nums2$ 中的数字 $b$,将 $a$ 和 $b$ 拼接成两个数字,取其中较小的数字即可。

时间复杂度 $(m + n)$,空间复杂度 $O(C)$。其中 $m$ 和 $n$ 分别是数组 $nums1$ 和 $nums2$ 的长度;而 $C$ 是数组 $nums1$ 和 $nums2$ 中数字的范围,本题中 $C = 10$。

**方法三:位运算**

由于数字的范围是 $1 \sim 9$,我们可以用一个长度为 $10$ 的二进制数来表示数组 $nums1$ 和 $nums2$ 中的数字。我们用 $mask1$ 表示数组 $nums1$ 中的数字,用 $mask2$ 表示数组 $nums2$ 中的数字。

如果 $mask1$ 和 $mask2$ 进行按位与得到的数字 $mask$ 不等于 $0$,那么我们提取 $mask$ 中最后一位 $1$ 所在的位置,即为最小的数字。

否则,我们分别提取 $mask1$ 和 $mask2$ 中最后一位 $1$ 所在的位置,分别记为 $a$ 和 $b$,那么最小的数字就是 $min(a \times 10 + b, b \times 10 + a)$。

时间复杂度 $O(m + n)$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别是数组 $nums1$ 和 $nums2$ 的长度。

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python
class Solution:
def minNumber(self, nums1: List[int], nums2: List[int]) -> int:
ans = 100
for a in nums1:
for b in nums2:
if a == b:
ans = min(ans, a)
else:
ans = min(ans, 10 * a + b, 10 * b + a)
return ans
```

```python
class Solution:
def minNumber(self, nums1: List[int], nums2: List[int]) -> int:
s = set(nums1) & set(nums2)
if s:
return min(s)
a, b = min(nums1), min(nums2)
return min(a * 10 + b, b * 10 + a)
```

```python
class Solution:
def minNumber(self, nums1: List[int], nums2: List[int]) -> int:
mask1 = mask2 = 0
for x in nums1:
mask1 |= 1 << x
for x in nums2:
mask2 |= 1 << x
mask = mask1 & mask2
if mask:
return (mask & -mask).bit_length() - 1
a = (mask1 & -mask1).bit_length() - 1
b = (mask2 & -mask2).bit_length() - 1
return min(a * 10 + b, b * 10 + a)
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
public int minNumber(int[] nums1, int[] nums2) {
int ans = 100;
for (int a : nums1) {
for (int b : nums2) {
if (a == b) {
ans = Math.min(ans, a);
} else {
ans = Math.min(ans, Math.min(a * 10 + b, b * 10 + a));
}
}
}
return ans;
}
}
```

```java
class Solution {
public int minNumber(int[] nums1, int[] nums2) {
boolean[] s1 = new boolean[10];
boolean[] s2 = new boolean[10];
for (int x : nums1) {
s1[x] = true;
}
for (int x : nums2) {
s2[x] = true;
}
int a = 0, b = 0;
for (int i = 1; i < 10; ++i) {
if (s1[i] && s2[i]) {
return i;
}
if (a == 0 && s1[i]) {
a = i;
}
if (b == 0 && s2[i]) {
b = i;
}
}
return Math.min(a * 10 + b, b * 10 + a);
}
}
```

```java
class Solution {
public int minNumber(int[] nums1, int[] nums2) {
int mask1 = 0, mask2 = 0;
for (int x : nums1) {
mask1 |= 1 << x;
}
for (int x : nums2) {
mask2 |= 1 << x;
}
int mask = mask1 & mask2;
if (mask != 0) {
return Integer.numberOfTrailingZeros(mask);
}
int a = Integer.numberOfTrailingZeros(mask1);
int b = Integer.numberOfTrailingZeros(mask2);
return Math.min(a * 10 + b, b * 10 + a);
}
}
```

### **C++**

```cpp
class Solution {
public:
int minNumber(vector<int>& nums1, vector<int>& nums2) {
int ans = 100;
for (int a : nums1) {
for (int b : nums2) {
if (a == b) {
ans = min(ans, a);
} else {
ans = min({ans, a * 10 + b, b * 10 + a});
}
}
}
return ans;
}
};
```

```cpp
class Solution {
public:
int minNumber(vector<int>& nums1, vector<int>& nums2) {
bitset<10> s1;
bitset<10> s2;
for (int x : nums1) {
s1[x] = 1;
}
for (int x : nums2) {
s2[x] = 1;
}
int a = 0, b = 0;
for (int i = 1; i < 10; ++i) {
if (s1[i] && s2[i]) {
return i;
}
if (!a && s1[i]) {
a = i;
}
if (!b && s2[i]) {
b = i;
}
}
return min(a * 10 + b, b * 10 + a);
}
};
```

```cpp
class Solution {
public:
int minNumber(vector<int>& nums1, vector<int>& nums2) {
int mask1 = 0, mask2 = 0;
for (int x : nums1) {
mask1 |= 1 << x;
}
for (int x : nums2) {
mask2 |= 1 << x;
}
int mask = mask1 & mask2;
if (mask) {
return __builtin_ctz(mask);
}
int a = __builtin_ctz(mask1);
int b = __builtin_ctz(mask2);
return min(a * 10 + b, b * 10 + a);
}
};
```

### **Go**

```go
func minNumber(nums1 []int, nums2 []int) int {
ans := 100
for _, a := range nums1 {
for _, b := range nums2 {
if a == b {
ans = min(ans, a)
} else {
ans = min(ans, min(a*10+b, b*10+a))
}
}
}
return ans
}

func min(a, b int) int {
if a < b {
return a
}
return b
}
```

```go
func minNumber(nums1 []int, nums2 []int) int {
s1 := [10]bool{}
s2 := [10]bool{}
for _, x := range nums1 {
s1[x] = true
}
for _, x := range nums2 {
s2[x] = true
}
a, b := 0, 0
for i := 1; i < 10; i++ {
if s1[i] && s2[i] {
return i
}
if a == 0 && s1[i] {
a = i
}
if b == 0 && s2[i] {
b = i
}
}
return min(a*10+b, b*10+a)
}

func min(a, b int) int {
if a < b {
return a
}
return b
}
```

```go
func minNumber(nums1 []int, nums2 []int) int {
var mask1, mask2 uint
for _, x := range nums1 {
mask1 |= 1 << x
}
for _, x := range nums2 {
mask2 |= 1 << x
}
if mask := mask1 & mask2; mask != 0 {
return bits.TrailingZeros(mask)
}
a, b := bits.TrailingZeros(mask1), bits.TrailingZeros(mask2)
return min(a*10+b, b*10+a)
}

func min(a, b int) int {
if a < b {
return a
}
return b
}
```

### **...**

```

```

<!-- tabs:end -->
Loading