【刷题】面试题17.11. 单词距离


题目

leetCode链接:https://leetcode.cn/problems/find-closest-lcci/

面试题17.11. 单词距离

有个内含单词的超大文本文件,给定任意两个不同的单词,找出在这个文件中这两个单词的最短距离(相隔单词数)。如果寻找过程在这个文件中会重复多次,而每次寻找的单词不同,你能对此优化吗?

示例:

输入:words = ["I","am","a","student","from","a","university","in","a","city"], word1 = "a", word2 = "student"
输出:1

思路

第一个想到的思路是暴力求解,对每个words中的word1,寻找它和每个word2之间的距离,去最小值,重复直到没有word1为止。复杂度过高( n 2 n^2 n2),直接pass。
第二个思路就是使用更简单的指针下标记录word1和word2的为止,从头开始遍历,如果发现单词为word1或者word2就记录下标,并计算两个下标距离和之前记录的距离取最小值即可。
对于进阶题,多个key对同一列表做查找很容易想到hash map存储每个单词对应的下标,这样就可以直接做查找了。首先将words放入hash map,然后对于查找的每一对单词,用两个指针(index1,index2)标记两个单词对应的下标list开头,然后按如下规则向后移动查找即可:

  1. 如果 index1 < index2,则将index1 移动到下一个word1 的下标;
  2. 如果 index1 > index2,则将index2 移动到下一个word2 的下标。

解题

python实现

class Solution:
    def findClosest(self, words: List[str], word1: str, word2: str) -> int:
        result = len(words)
        i1 = -1
        i2 = -1
        for k,v in enumerate(words):
            if v==word1:
                i1=k
            if v==word2:
                i2=k
            if i1>=0 and i2>=0:
                result=min(result,abs(i1-i2))
        return result

golang实现

func findClosest(words []string, word1 string, word2 string) int {
	result := len(words)
	i1, i2 := -1, -1
	for k, v := range words {
		if v == word1 {
			i1 = k
		} else if v == word2 {
			i2 = k
		}
		if i1 >= 0 && i2 >= 0 {
			result = min(result, abs(i1-i2))
		}
	}
	return result
}

func min(a, b int) int {
	if a > b {
		return b
	}
	return a
}

func abs(a int) int {
	if a >= 0 {
		return a
	}
	return -a
}

进阶

python实现

class Solution:
    def findMoreClosest(self, words: List[str], word_pairs: List[List[str]]) -> List[int]:
        hash_map = dict()
        for k, v in enumerate(words):
            if v not in hash_map.keys():
                hash_map[v] = [k]
            else:
                hash_map[v].append(k)
        result = []
        for pairs in word_pairs:
            word1 = pairs[0]
            word2 = pairs[1]
            word1_index_list = hash_map.get(word1, [])
            word2_index_list = hash_map.get(word2, [])
            ans = len(words)
            i, j = 0, 0
            while i < len(word1_index_list) and j < len(word2_index_list):
                i1 = word1_index_list[i]
                i2 = word2_index_list[j]
                ans = min(ans, abs(i1 - i2))
                if i1 < i2:
                    i += 1
                else:
                    j += 1
            result.append(ans)
        return result

golang实现

懒得写了基本就是转译一下上面的python吧


复杂度

时间复杂度 O ( n ) O(n) O(n),只需要遍历一次列表。进阶算法对于输入的每一对word1和word2,复杂度为 O ( n ) O(n) O(n),其中放入hash map复杂度为 O ( n ) O(n) O(n),双指针遍历复杂度为 O ( n ) O(n) O(n)

空间复杂度 O ( 1 ) O(1) O(1)。进阶算法复杂度为 O ( n ) O(n) O(n),即为hash map占据空间大小。


总结

昨日遇到困难睡大觉了,今日没啥好说的,较为简单思路也很清晰的题目。
进阶版本双指针遍历思路需要多看一下,比我之前自己写的优雅太多了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值