题目来源:🔒LeetCode243:最短单词距离
问题抽象: 给定一个 字符串数组 words 和两个 不同字符串 word1 与 word2(题目保证它们均在数组中),要求找出它们在数组中所有出现位置索引差的绝对最小值(即最短单词距离),满足以下核心需求:
-
距离定义与计算规则:
- 距离定义为
word1和word2在数组中的任意两个索引i和j的差的绝对值|i - j|; - 需遍历数组一次,在遇到
word1或word2时,动态更新其最近索引,并计算与另一单词最近索引的当前距离,从而维护全局最小距离。
- 距离定义为
-
计算约束:
- 时间复杂度 O(n)(其中 n 是数组长度,仅需单次遍历);
- 空间复杂度 O(1)(仅使用常数个变量存储
word1和word2的最近索引以及最小距离值)。
-
边界处理:
- 输入数组非空(长度至少为 2),且
word1和word2不同、均存在(题目保证); - 最小距离至少为 1(索引不同),最大不超过数组长度减 1;
- 特殊边界:数组长度为 2 时,距离恒为 1;若单词多次出现,需考虑所有可能索引对。
- 输入数组非空(长度至少为 2),且
输入:字符串数组 words,字符串 word1,字符串 word2
输出:整数(最短距离,值域为 1 到数组长度减 1)。
解题思路
计算两个单词在列表中的最小位置差,核心在于如何高效记录并更新位置信息。常见两种解法:
-
暴力解法(不推荐):
- 遍历数组,分别存储
word1和word2的所有位置到两个列表(空间O(n))。 - 双重循环计算每对位置的距离(时间
O(n²))。 - 效率低,适用于位置较少的情况。
- 遍历数组,分别存储
-
单次遍历优化(最优解):
- 使用两个指针
index1和index2动态记录word1和word2最近出现的索引,初始化为-1。 - 遍历数组:
- 遇到
word1则更新index1 = 当前索引。 - 遇到
word2则更新index2 = 当前索引。 - 若
index1和index2均不为-1(即两个单词均已出现),计算距离并更新最小值。
- 遇到
- 时间复杂度
O(n):仅需一次遍历。 - 空间复杂度
O(1):仅需常量空间存储指针和最小值。
- 使用两个指针
为何能保证最小距离?
每次遇到任一单词时,其位置都是当前最新位置。此时计算的距离是当前已知的局部最小距离,全局最小距离一定在某个局部被捕获。
代码实现(Java版)🔥点击下载源码
class Solution {
public int shortestDistance(String[] words, String word1, String word2) {
// 初始化指针:index1 记录 word1 最近位置,index2 记录 word2 最近位置
int index1 = -1, index2 = -1;
// minDistance 记录最小距离,初始化为数组长度(最大可能值)
int minDistance = words.length;
for (int i = 0; i < words.length; i++) {
// 更新 word1 的最近位置
if (words[i].equals(word1)) {
index1 = i;
}
// 更新 word2 的最近位置(注意:不能用 else if,因为可能连续出现两个单词)
if (words[i].equals(word2)) {
index2 = i;
}
// 当两个单词均已出现过时,计算当前距离并更新最小值
if (index1 != -1 && index2 != -1) {
minDistance = Math.min(minDistance, Math.abs(index1 - index2));
}
}
return minDistance;
}
}
代码说明
-
指针初始化:
index1和index2初始为-1,表示尚未遇到对应单词。
-
遍历更新逻辑:
- 使用独立的
if语句(非else if)处理边界情况:当word1和word2相邻时,需同时更新两个指针(例如输入["a", "b"],word1="a",word2="b")。
- 使用独立的
-
距离更新条件:
- 仅当两个指针均不为
-1时才更新距离,避免无效计算(如一个单词未出现时)。
- 仅当两个指针均不为
-
提前终止优化:
- 若题目允许,可添加
if (minDistance == 1) break;(最小可能值为 1),但本题数据量下收益有限,故未添加。
- 若题目允许,可添加

1247

被折叠的 条评论
为什么被折叠?



