题目
假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。
你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设答案总是存在。
示例
输入: list1 = ["Shogun", "Tapioca Express", "Burger King", "KFC"],list2 = ["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"]
输出: ["Shogun"]
解释: 他们唯一共同喜爱的餐厅是“Shogun”。
输入:list1 = ["Shogun", "Tapioca Express", "Burger King", "KFC"],list2 = ["KFC", "Shogun", "Burger King"]
输出: ["Shogun"]
解释: 他们共同喜爱且具有最小索引和的餐厅是“Shogun”,它有最小的索引和1(0+1)。
解法一:哈希表
题目的要求找出最小索引和,因此我们的主要任务点有两个:一,找出两个人共同喜欢的餐厅;二,找出两个人共同喜欢的餐厅的最小索引。针对问题一,我们很容易想到使用Map结构,在解题时,这种查询重复元素的问题使用Map往往能使问题更加简单。针对问题二,由于需要找出最小索引,因此我们需要一个标签记录最小索引,其主要分支有三种:
-
当目前索引和大于最小索引,不做处理;
-
当当前索引和等于最小索引,把当前餐厅加入结果集;
-
当当前索引和小于最小索引,清空结果集,更新最小索引并把当前餐厅加入结果集。
具体代码实现如下:
class Solution {
public String[] findRestaurant(String[] list1, String[] list2) {
List<String> ans = new LinkedList<>();
Map<String,Integer> map = new HashMap<>();
int i = 0;
//把list1中所有餐厅及其索引入map,方便进行相同餐厅筛选
for(String str:list1){
map.put(str,i);
++i;
}
//初始化最小索引为最大值
int min_Index = Integer.MAX_VALUE;
i = 0;
for(String str:list2){
//若当前餐厅为共同喜爱餐厅,进行三个分支处理
if(map.containsKey(str)){
int index = i + map.get(str);
//若小于,清空结果集,更新最小索引并把当前餐厅加入结果集。
if(min_Index > index){
min_Index = index;
ans.clear();
ans.add(str);
}else if(min_Index == index){
//若等于,把当前餐厅加入结果集
ans.add(str);
}
}
++i;
}
String[] answer = ans.toArray(new String[0]);
return answer;
}
}
其执行效果如下:
136 / 136 个通过测试用例
状态:通过
执行用时: 8 ms
内存消耗: 41.8 MB
提交时间:13 分钟前
其时间复杂度为O(n+m)。
解法二:优化
考虑对解法一算法优化,我们可以发现:当在遍历第二个数组的时候,若当前索引已经大于最小索引,则可以提前跳出循环。因此我们可以选择两条链中较短的数组入库,降低两链长度不平衡时的性能浪费。
其代码实现如下:
class Solution {
public String[] findRestaurant(String[] list1, String[] list2) {
List<String> ans = new LinkedList<>();
Map<String,Integer> map = new HashMap<>();
//Map记录短链
if(list1.length > list2.length){
return findRestaurant(list2,list1);
}
int i = 0;
//把list1中所有餐厅及其索引入map,方便进行相同餐厅筛选
for(String str:list1){
map.put(str,i);
++i;
}
//初始化最小索引为最大值
int min_Index = Integer.MAX_VALUE;
i = 0;
for(String str:list2){
//若当前索引大于最小索引,退出循环
if(i > min_Index){
break;
}
//若当前餐厅为共同喜爱餐厅,进行三个分支处理
if(map.containsKey(str)){
int index = i + map.get(str);
//若小于,清空结果集,更新最小索引并把当前餐厅加入结果集。
if(min_Index > index){
min_Index = index;
ans.clear();
ans.add(str);
}else if(min_Index == index){
//若等于,把当前餐厅加入结果集
ans.add(str);
}
}
++i;
}
String[] answer = ans.toArray(new String[0]);
return answer;
}
}
其执行效果如下:
136 / 136 个通过测试用例
状态:通过
执行用时: 5 ms
内存消耗: 42.3 MB
提交时间:3 分钟前