题目描述
假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。
你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设答案总是存在。
示例
示例 1
输入: list1 = ["Shogun", "Tapioca Express", "Burger King", "KFC"],list2 = ["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"]
输出: ["Shogun"]
解释: 他们唯一共同喜爱的餐厅是“Shogun”
示例 2
输入:list1 = ["Shogun", "Tapioca Express", "Burger King", "KFC"],list2 = ["KFC", "Shogun", "Burger King"]
输出: ["Shogun"]
解释: 他们共同喜爱且具有最小索引和的餐厅是“Shogun”,它有最小的索引和1(0+1)。
题解
● 创建哈希表:使用哈希表 indexMapB 来存储 listB 中的元素及其索引。
● 遍历 listA:对于 listA 中的每个元素,检查它是否存在于 indexMapB 中。
● 计算索引和:如果存在,计算 listA 中的当前索引与 listB 中对应索引的和。
● 记录最小索引和:使用变量 minIndexSum 来记录最小的索引和,并更新一个结果列表 result 来存储所有具有最小索引和的元素对。
● 返回结果:返回结果列表 result
代码实现
vector<string> findRestaurant(vector<string>& listA,
vector<string>& listB) {
unordered_map<string, int> indexMapB;
// 创建哈希表,存储 listB 中的元素及其索引
for (int i = 0; i < listB.size(); ++i) {
indexMapB[listB[i]] = i;
}
vector<string> result;
int minIndexSum = INT_MAX;
// 遍历 listA
for (int i = 0; i < listA.size(); ++i) {
auto it = indexMapB.find(listA[i]);
// 如果 listA 中的元素也在 listB 中
if (it != indexMapB.end()) {
int indexSum = i + it->second; // 计算索引和
if (indexSum < minIndexSum) {
minIndexSum = indexSum; // 更新最小索引和
result.clear(); // 清空结果列表
result.push_back(listA[i]); // 添加新元素
} else if (indexSum == minIndexSum) {
result.push_back(listA[i]); // 添加相同索引和的元素
}
}
}
return result;
}
复杂度分析
● 时间复杂度:O(n + m),其中 n 是 listA 的长度,m 是 listB 的长度。我们只需要遍历两个列表一次来构建哈希表和检查 listA 中的元素。
● 空间复杂度:O(m),用于存储 listB 的哈希表。
这个算法通过使用哈希表来快速查找 listB 中的元素,避免了排序的需要,提高了效率。