一、题目描述
假设 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)。
提示:
1 <= list1.length, list2.length <= 1000
1 <= list1[i].length, list2[i].length <= 30
list1[i]
和list2[i]
由空格' '
和英文字母组成。list1
的所有字符串都是 唯一 的。list2
中的所有字符串都是 唯一 的。
二、解题思路
-
首先,我们需要一个数据结构来存储每个餐厅名字及其在两个列表中的索引。这里我们可以使用一个哈希表(HashMap)。
-
遍历第一个列表
list1
,将每个餐厅的名字和它的索引存入哈希表中。 -
接着,遍历第二个列表
list2
,对于每个餐厅名字,检查它是否在哈希表中存在,如果存在,则计算索引和(该餐厅在list1
中的索引加上在list2
中的索引)。 -
我们需要找到最小的索引和,因此我们可以维护一个变量来记录当前的最小索引和,并在遍历过程中更新它。
-
如果找到一个更小的索引和,我们就更新结果列表;如果找到一个与当前最小索引和相同的索引和,则将该餐厅添加到结果列表中。
-
最后,返回结果列表。
三、具体代码
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class Solution {public String[] findRestaurant(String[] list1, String[] list2) {// 使用HashMap存储list1中餐厅的名字和对应的索引Map<String, Integer> indexMap = new HashMap<>();for (int i = 0; i < list1.length; i++) {indexMap.put(list1[i], i);}// 初始化最小索引和为最大可能值int minSum = Integer.MAX_VALUE;// 使用List来存储结果List<String> result = new ArrayList<>();// 遍历list2for (int i = 0; i < list2.length; i++) {if (indexMap.containsKey(list2[i])) {int sum = i + indexMap.get(list2[i]); // 计算索引和// 如果找到更小的索引和,则更新结果列表和最小索引和if (sum < minSum) {result.clear();result.add(list2[i]);minSum = sum;} else if (sum == minSum) { // 如果索引和相同,则添加到结果列表result.add(list2[i]);}}}// 将结果列表转换为数组并返回return result.toArray(new String[0]);}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
-
第一个
for
循环遍历list1
数组,其长度为n
(假设list1
的长度为n
),这个循环的时间复杂度是O(n)。 -
第二个
for
循环遍历list2
数组,其长度为m
(假设list2
的长度为m
),这个循环的时间复杂度是O(m)。 -
在第二个循环中,我们调用了
containsKey
方法,这是一个常数时间操作,其时间复杂度是O(1)。 -
add
和clear
方法在ArrayList
中的时间复杂度都是O(1)。
综上所述,总的时间复杂度是O(n + m),因为两个循环是独立的,我们只需将它们的时间复杂度相加。
2. 空间复杂度
-
indexMap
是一个哈希表,用于存储list1
中所有餐厅名字及其索引。在最坏的情况下,如果list1
中的每个元素都是唯一的,那么indexMap
将包含n
个条目。因此,空间复杂度是O(n)。 -
result
是一个列表,用于存储共同喜爱的餐厅。在最坏的情况下,如果list1
和list2
完全相同,那么result
将包含所有n
个餐厅。因此,空间复杂度是O(n)。
综上所述,总的空间复杂度是O(n),因为indexMap
和result
是独立的数据结构,且indexMap
占据了主要的存储空间。
五、总结知识点
-
类定义:
public class Solution
:定义了一个公共类Solution
。
-
方法定义:
public String[] findRestaurant(String[] list1, String[] list2)
:定义了一个公共方法findRestaurant
,它接受两个字符串数组作为参数,并返回一个字符串数组。
-
数据结构:
HashMap<String, Integer>
:使用哈希表来存储键值对,其中键是字符串(餐厅名字),值是整数(索引)。ArrayList<String>
:使用动态数组来存储结果列表。
-
循环:
for
循环:用于遍历数组。
-
哈希表操作:
put
:将键值对存入哈希表。containsKey
:检查哈希表中是否包含指定的键。get
:根据键获取哈希表中的值。
-
数组与列表转换:
toArray
:将列表转换为数组。
-
条件语句:
if
:用于条件判断。else if
:用于处理多个条件分支。
-
变量操作:
- 变量赋值:例如
minSum = sum;
。 - 变量比较:例如
if (sum < minSum)
。
- 变量赋值:例如
-
常量:
Integer.MAX_VALUE
:Java中定义的整型最大值常量。
-
集合操作:
clear
:清空列表中的所有元素。add
:向列表中添加元素。
-
返回值:
return
:用于从方法中返回值。
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。