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
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
---
comments: true
difficulty: 简单
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3740.Minimum%20Distance%20Between%20Three%20Equal%20Elements%20I/README.md
---

<!-- problem:start -->

# [3740. 三个相等元素之间的最小距离 I](https://leetcode.cn/problems/minimum-distance-between-three-equal-elements-i)

[English Version](/solution/3700-3799/3740.Minimum%20Distance%20Between%20Three%20Equal%20Elements%20I/README_EN.md)

## 题目描述

<!-- description:start -->

<p>给你一个整数数组 <code>nums</code>。</p>

<p>如果满足 <code>nums[i] == nums[j] == nums[k]</code>,且 <code>(i, j, k)</code> 是 3 个&nbsp;<strong>不同&nbsp;</strong>下标,那么三元组 <code>(i, j, k)</code> 被称为&nbsp;<strong>有效三元组&nbsp;</strong>。</p>

<p><strong>有效三元组&nbsp;</strong>的&nbsp;<strong>距离&nbsp;</strong>被定义为 <code>abs(i - j) + abs(j - k) + abs(k - i)</code>,其中 <code>abs(x)</code> 表示 <code>x</code> 的&nbsp;<strong>绝对值&nbsp;</strong>。</p>

<p>返回一个整数,表示 <strong>有效三元组&nbsp;</strong>的&nbsp;<strong>最小&nbsp;</strong>可能距离。如果不存在&nbsp;<strong>有效三元组&nbsp;</strong>,返回 <code>-1</code>。</p>

<p>&nbsp;</p>

<p><strong class="example">示例 1:</strong></p>

<div class="example-block">
<p><strong>输入:</strong> <span class="example-io">nums = [1,2,1,1,3]</span></p>

<p><strong>输出:</strong> <span class="example-io">6</span></p>

<p><strong>解释:</strong></p>

<p>最小距离对应的有效三元组是&nbsp;<code>(0, 2, 3)</code>&nbsp;。</p>

<p><code>(0, 2, 3)</code> 是一个有效三元组,因为 <code>nums[0] == nums[2] == nums[3] == 1</code>。它的距离为 <code>abs(0 - 2) + abs(2 - 3) + abs(3 - 0) = 2 + 1 + 3 = 6</code>。</p>
</div>

<p><strong class="example">示例 2:</strong></p>

<div class="example-block">
<p><strong>输入:</strong> <span class="example-io">nums = [1,1,2,3,2,1,2]</span></p>

<p><strong>输出:</strong> <span class="example-io">8</span></p>

<p><strong>解释:</strong></p>

<p>最小距离对应的有效三元组是&nbsp;<code>(2, 4, 6)</code>&nbsp;。</p>

<p><code>(2, 4, 6)</code> 是一个有效三元组,因为 <code>nums[2] == nums[4] == nums[6] == 2</code>。它的距离为 <code>abs(2 - 4) + abs(4 - 6) + abs(6 - 2) = 2 + 2 + 4 = 8</code>。</p>
</div>

<p><strong class="example">示例 3:</strong></p>

<div class="example-block">
<p><strong>输入:</strong> <span class="example-io">nums = [1]</span></p>

<p><strong>输出:</strong> <span class="example-io">-1</span></p>

<p><strong>解释:</strong></p>

<p>不存在有效三元组,因此答案为 -1。</p>
</div>

<p>&nbsp;</p>

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

<ul>
<li><code>1 &lt;= n == nums.length &lt;= 100</code></li>
<li><code>1 &lt;= nums[i] &lt;= n</code></li>
</ul>

<!-- description:end -->

## 解法

<!-- solution:start -->

### 方法一:哈希表

我们可以使用一个哈希表 $\textit{g}$ 来存储数组中每个数字对应的下标列表。遍历数组时,将每个数字的下标添加到哈希表中对应的列表中。定义一个变量 $\textit{ans}$ 来存储答案,初始值设为无穷大 $\infty$。

接下来,我们遍历哈希表中的每个下标列表。如果某个数字的下标列表长度大于等于 $3$,则说明存在有效三元组。要使得距离最小,我们可以选择该数字下标列表中相邻的三个下标 $i$、$j$ 和 $k$,假设 $i \lt; j \lt; k$,则该三元组的距离为 $j - i + k - j + k - i = 2 \times (k - i)$。我们遍历该下表列表所有相邻的三个下标组合,计算距离并更新答案。

最终,如果答案仍然是初始值 $\infty$,则说明不存在有效三元组,返回 $-1$;否则返回计算得到的最小距离。

时间复杂度 $O(n)$,空间复杂度 $O(n)$,其中 $n$ 是数组的长度。

<!-- tabs:start -->

#### Python3

```python
class Solution:
def minimumDistance(self, nums: List[int]) -> int:
g = defaultdict(list)
for i, x in enumerate(nums):
g[x].append(i)
ans = inf
for ls in g.values():
for h in range(len(ls) - 2):
i, k = ls[h], ls[h + 2]
ans = min(ans, (k - i) * 2)
return -1 if ans == inf else ans
```

#### Java

```java
class Solution {
public int minimumDistance(int[] nums) {
int n = nums.length;
Map<Integer, List<Integer>> g = new HashMap<>();
for (int i = 0; i < n; ++i) {
g.computeIfAbsent(nums[i], k -> new ArrayList<>()).add(i);
}
final int inf = 1 << 30;
int ans = inf;
for (var ls : g.values()) {
int m = ls.size();
for (int h = 0; h < m - 2; ++h) {
int i = ls.get(h);
int k = ls.get(h + 2);
int t = (k - i) * 2;
ans = Math.min(ans, t);
}
}
return ans == inf ? -1 : ans;
}
}
```

#### C++

```cpp
class Solution {
public:
int minimumDistance(vector<int>& nums) {
int n = nums.size();
unordered_map<int, vector<int>> g;
for (int i = 0; i < n; ++i) {
g[nums[i]].push_back(i);
}
const int inf = 1 << 30;
int ans = inf;
for (auto& [_, ls] : g) {
int m = ls.size();
for (int h = 0; h < m - 2; ++h) {
int i = ls[h];
int k = ls[h + 2];
int t = (k - i) * 2;
ans = min(ans, t);
}
}
return ans == inf ? -1 : ans;
}
};
```

#### Go

```go
func minimumDistance(nums []int) int {
g := make(map[int][]int)
for i, x := range nums {
g[x] = append(g[x], i)
}

inf := 1 << 30
ans := inf

for _, ls := range g {
m := len(ls)
for h := 0; h < m-2; h++ {
i := ls[h]
k := ls[h+2]
t := (k - i) * 2
ans = min(ans, t)
}
}

if ans == inf {
return -1
}
return ans
}
```

#### TypeScript

```ts
function minimumDistance(nums: number[]): number {
const n = nums.length;
const g = new Map<number, number[]>();

for (let i = 0; i < n; i++) {
if (!g.has(nums[i])) {
g.set(nums[i], []);
}
g.get(nums[i])!.push(i);
}

const inf = 1 << 30;
let ans = inf;

for (const ls of g.values()) {
const m = ls.length;
for (let h = 0; h < m - 2; h++) {
const i = ls[h];
const k = ls[h + 2];
const t = (k - i) * 2;
ans = Math.min(ans, t);
}
}

return ans === inf ? -1 : ans;
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
Loading