Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
1、题目描述
请设计一个类,使该类的构造函数能够接收一个字符串数组。然后再实现一个方法,该方法能够分别接收两个单词,并返回列表中这两个单词之间的最短距离。
实现 WordDistanc 类:
WordDistance(String[] wordsDict) 用字符串数组 wordsDict 初始化对象。
int shortest(String word1, String word2) 返回数组 worddict 中 word1 和 word2 之间的最短距离。
示例 1:
输入:
["WordDistance", "shortest", "shortest"]
[[["practice", "makes", "perfect", "coding", "makes"]], ["coding", "practice"], ["makes", "coding"]]
输出:
[null, 3, 1
解释:
WordDistance wordDistance = new WordDistance(["practice", "makes", "perfect", "coding", "makes"]);
wordDistance.shortest("coding", "practice"); // 返回 3
wordDistance.shortest("makes", "coding"); // 返回 1
注意:
1 <= wordsDict.length <= 3 * 104
1 <= wordsDict[i].length <= 10
wordsDict[i] 由小写英文字母组成
word1 和 word2 在数组 wordsDict 中
word1 != word2
shortest 操作次数不大于 5000
2、思路分析
我们需要使用哈希表来记录给出每一个单词的位置,查询的时候可以根据单词拿到其出现的位置,找到两个单词出现位置中距离最近的即可。
- 使用哈希表记录单词出现位置
let wordMap = {};
for(let i = 0; i < wordsDict.length; i++){
wordMap[wordsDict[i]] ? wordMap[wordsDict[i]].push(i) : wordMap[wordsDict[i]] = [i];
}
- 找到两个单词最近距离
let d1 = this.wordMap[word1],d2 = this.wordMap[word2];
let res = Infinity;
for(let i = 0; i < d1.length; i++){
for(let j = 0; j < d2.length; j++){
res = Math.min(Math.abs(d1[i] - d2[j]),res);
}
}
3、AC代码
/**
* @param {string[]} wordsDict
*/
var WordDistance = function(wordsDict) {
let wordMap = {};
for(let i = 0; i < wordsDict.length; i++){
wordMap[wordsDict[i]] ? wordMap[wordsDict[i]].push(i) : wordMap[wordsDict[i]] = [i];
}
this.wordMap = wordMap;
};
/**
* @param {string} word1
* @param {string} word2
* @return {number}
*/
WordDistance.prototype.shortest = function(word1, word2) {
let d1 = this.wordMap[word1],d2 = this.wordMap[word2];
let res = Infinity;
for(let i = 0; i < d1.length; i++){
for(let j = 0; j < d2.length; j++){
res = Math.min(Math.abs(d1[i] - d2[j]),res);
}
}
return res;
};
/**
* Your WordDistance object will be instantiated and called as such:
* var obj = new WordDistance(wordsDict)
* var param_1 = obj.shortest(word1,word2)
*/
4、题目延伸
题库中还有一道扩展题,题目如下:
(1)题目描述
给定一个字符串数组 wordsDict 和两个字符串 word1 和 word2 ,返回列表中这两个单词之间的最短距离。
注意:word1 和 word2 是有可能相同的,并且它们将分别表示为列表中 两个独立的单词 。
示例 1:
输入:wordsDict = ["practice", "makes", "perfect", "coding", "makes"], word1 = "makes", word2 = "coding"
输出:1
示例 2:
输入:wordsDict = ["practice", "makes", "perfect", "coding", "makes"], word1 = "makes", word2 = "makes"
输出:3
提示:
1 <= wordsDict.length <= 105
1 <= wordsDict[i].length <= 10
wordsDict[i] 由小写英文字母组成
word1 和 word2 都在 wordsDict 中
(2)思路分析
这一道题目与前面那道题目只有一个区别,就是在这道题目中word1 和 word2 是有可能相同的,并且它们将分别表示为列表中 两个独立的单词 ,也就是说两个相同单词的最短距离不是0,我们需要特殊处理一下。
if(word1 == word2){
for(let i = 1; i < d1.length; i++){
res = Math.min(d1[i] - d1[i - 1],res);
}
return res;
}
(3)AC代码
/**
* @param {string[]} wordsDict
* @param {string} word1
* @param {string} word2
* @return {number}
*/
var shortestWordDistance = function(wordsDict, word1, word2) {
let wordMap = {};
for(let i = 0; i < wordsDict.length; i++){
wordMap[wordsDict[i]] ? wordMap[wordsDict[i]].push(i) : wordMap[wordsDict[i]] = [i];
}
let d1 = wordMap[word1],d2 = wordMap[word2];
let res = Infinity;
if(word1 == word2){
for(let i = 1; i < d1.length; i++){
res = Math.min(d1[i] - d1[i - 1],res);
}
return res;
}
for(let i = 0; i < d1.length; i++){
for(let j = 0; j < d2.length; j++){
res = Math.min(Math.abs(d1[i] - d2[j]),res);
}
}
return res;
};