245. Shortest Word Distance II
leetcode medium
Task
Дан массив строк wordsDict и две строки word1 и word2, которые уже существуют в массиве. Верните наименьшее расстояние между вхождениями этих двух слов в списке.
Обратите внимание, что word1 и word2 могут быть одинаковыми. Гарантируется, что они представляют собой два отдельных слова в списке.
Пример
Input: wordsDict = ["practice", "makes", "perfect", "coding", "makes"], word1 = "makes", word2 = "coding"
Output: 1
C# solution
matched/originalusing System;
using System.Collections.Generic;
public class Solution {
public int ShortestWordDistance(string[] wordsDict, string word1, string word2) {
List<int> indices1 = new List<int>();
List<int> indices2 = new List<int>();
for (int i = 0; i < wordsDict.Length; i++) {
if (wordsDict[i] == word1) {
indices1.Add(i);
}
if (wordsDict[i] == word2) {
indices2.Add(i);
}
}
int shortestDistance = int.MaxValue;
foreach (int index in indices1) {
int x = indices2.BinarySearch(index);
if (x < 0) {
x = ~x;
}
if (x < indices2.Count) {
shortestDistance = Math.Min(shortestDistance, indices2[x] - index);
}
if (x > 0 && indices2[x - 1] != index) {
shortestDistance = Math.Min(shortestDistance, index - indices2[x - 1]);
}
}
return shortestDistance;
}
}C++ solution
auto-draft, review before submit#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
public int ShortestWordDistance(vector<string> wordsDict, string word1, string word2) {
List<int> indices1 = new List<int>();
List<int> indices2 = new List<int>();
for (int i = 0; i < wordsDict.size(); i++) {
if (wordsDict[i] == word1) {
indices1.push_back(i);
}
if (wordsDict[i] == word2) {
indices2.push_back(i);
}
}
int shortestDistance = int.MaxValue;
foreach (int index in indices1) {
int x = indices2.BinarySearch(index);
if (x < 0) {
x = ~x;
}
if (x < indices2.size()) {
shortestDistance = min(shortestDistance, indices2[x] - index);
}
if (x > 0 && indices2[x - 1] != index) {
shortestDistance = min(shortestDistance, index - indices2[x - 1]);
}
}
return shortestDistance;
}
}Java solution
matched/originalimport java.util.*;
class Solution {
public int shortestWordDistance(String[] wordsDict, String word1, String word2) {
List<Integer> indices1 = new ArrayList<>();
List<Integer> indices2 = new ArrayList<>();
for (int i = 0; i < wordsDict.length; i++) {
if (wordsDict[i].equals(word1)) {
indices1.add(i);
}
if (wordsDict[i].equals(word2)) {
indices2.add(i);
}
}
int shortestDistance = Integer.MAX_VALUE;
for (int index : indices1) {
int x = Collections.binarySearch(indices2, index);
if (x < 0) {
x = -x - 1;
}
if (x < indices2.size()) {
shortestDistance = Math.min(shortestDistance, indices2.get(x) - index);
}
if (x > 0 && !indices2.get(x - 1).equals(index)) {
shortestDistance = Math.min(shortestDistance, index - indices2.get(x - 1));
}
}
return shortestDistance;
}
}JavaScript solution
matched/originalclass Solution {
shortestWordDistance(wordsDict, word1, word2) {
const indices1 = [];
const indices2 = [];
wordsDict.forEach((word, i) => {
if (word === word1) {
indices1.push(i);
}
if (word === word2) {
indices2.push(i);
}
});
let shortestDistance = Infinity;
indices1.forEach(index => {
const x = indices2.findIndex(i => i > index);
if (x !== -1) {
shortestDistance = Math.min(shortestDistance, indices2[x] - index);
}
if (x > 0 && indices2[x - 1] !== index) {
shortestDistance = Math.min(shortestDistance, index - indices2[x - 1]);
}
});
return shortestDistance;
}
}Python solution
matched/originalfrom bisect import bisect_right
class Solution:
def shortestWordDistance(self, wordsDict, word1, word2):
indices1 = [i for i, word in enumerate(wordsDict) if word == word1]
indices2 = [i for i, word in enumerate(wordsDict) if word == word2]
shortestDistance = float('inf')
for index in indices1:
x = bisect_right(indices2, index)
if x < len(indices2):
shortestDistance = min(shortestDistance, indices2[x] - index)
if x > 0 and indices2[x - 1] != index:
shortestDistance = min(shortestDistance, index - indices2[x - 1])
return shortestDistanceGo solution
matched/originalpackage main
import (
"math"
"sort"
)
func shortestWordDistance(wordsDict []string, word1 string, word2 string) int {
var indices1, indices2 []int
for i, word := range wordsDict {
if word == word1 {
indices1 = append(indices1, i)
}
if word == word2 {
indices2 = append(indices2, i)
}
}
shortestDistance := math.MaxInt32
for _, index := range indices1 {
x := sort.Search(len(indices2), func(i int) bool { return indices2[i] > index })
if x < len(indices2) {
shortestDistance = min(shortestDistance, indices2[x]-index)
}
if x > 0 && indices2[x-1] != index {
shortestDistance = min(shortestDistance, index-indices2[x-1])
}
}
return shortestDistance
}
func min(a, b int) int {
if a < b {
return a
}
return b
}Explanation
Algorithm
1️⃣
Переберите список wordsDict и сохраните индексы слова word1 в список indices1 и индексы слова word2 в список indices2. Инициализируйте переменную shortestDistance = INT_MAX.
2️⃣
Переберите индексы в списке indices1 и для каждого индекса найдите верхнюю границу в списке indices2, используя бинарный поиск, и сохраните этот индекс в переменную x. Рассмотрите индексы indices2[x] и indices2[x - 1], обновляя shortestDistance, если индексы не совпадают.
3️⃣
Верните значение переменной shortestDistance.
😎