最短单词距离

Submission

运行时间: 23 ms

内存: 18.4 MB

class Solution:
    def shortestDistance(self, wordsDict: List[str], word1: str, word2: str) -> int:
        index1 = []
        index2 = []
        for i in range(len(wordsDict)):
            if wordsDict[i] == word1:
                index1.append(i)
            if wordsDict[i] == word2:
                index2.append(i)
        ans = []
        for i in range(len(index1)):
            for j in range(len(index2)):
                ans.append(abs(index1[i]-index2[j]))
        return min(ans)

Explain

该题解的思路是先遍历一遍单词列表,将字符串 word1 和 word2 出现的位置分别记录在 index1 和 index2 两个列表中。然后使用两个嵌套循环,计算 index1 中每个位置与 index2 中每个位置的绝对差值,并存入 ans 列表。最后返回 ans 列表中的最小值,即为最短单词距离。

时间复杂度: O(n^2)

空间复杂度: O(n^2)

class Solution:
    def shortestDistance(self, wordsDict: List[str], word1: str, word2: str) -> int:
        # 记录 word1 出现的位置
        index1 = []
        # 记录 word2 出现的位置
        index2 = []
        # 遍历单词列表
        for i in range(len(wordsDict)):
            if wordsDict[i] == word1:
                index1.append(i)
            if wordsDict[i] == word2:
                index2.append(i)
        # 存储所有可能的距离
        ans = []
        # 双重循环计算距离
        for i in range(len(index1)):
            for j in range(len(index2)):
                ans.append(abs(index1[i]-index2[j]))
        # 返回最短距离
        return min(ans)

Explore

是的,有更高效的方法可以避免嵌套循环中的冗余计算。一种方法是使用双指针技术。首先,保持两个指针分别指向两个列表(index1 和 index2)。然后,比较两个指针指向的元素来确定哪个较小,并只移动较小元素的指针。每次移动指针时,计算两个指针指向的元素之间的距离,并更新最短距离。这种方法只需要线性时间复杂度,即 O(m + n),其中 m 和 n 分别为两个列表的长度。

实际上可以在遍历过程中即时更新最短距离。通过使用一个变量来存储当前的最短距离,每次计算两个位置的距离时,立即比较并更新这个最短距离变量,这样就无需存储所有距离。这种即时更新策略显著降低了空间复杂度,从 O(m * n) 减少到 O(1)。

使用两个独立的 if 语句确实可能导致在某些情况下性能稍微下降,尤其是当 word1 和 word2 频繁交替出现时,因为每次遍历都需要分别检查两次。然而,这种性能下降通常是微小的,因为检查字符串相等性通常很快。如果对性能有极端要求,可以考虑使用一种更复杂的数据结构,例如字典,来一次遍历中处理所有单词的位置记录。

是的,这种做法确实会导致不必要的内存使用,尤其是当 index1 和 index2 的长度很大时。存储所有可能的位置差值可能导致内存消耗大量增加。更有效的做法是使用上述提到的即时更新策略,即在计算距离时直接更新最短距离,而不是存储所有距离。这样可以显著减少内存使用,只需维持几个变量即可。