LeetCode题练习与总结:两个列表的最小索引总和--599

一、题目描述

假设 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 中的所有字符串都是 唯一 的。

二、解题思路

  1. 首先,我们需要一个数据结构来存储每个餐厅名字及其在两个列表中的索引。这里我们可以使用一个哈希表(HashMap)。

  2. 遍历第一个列表list1,将每个餐厅的名字和它的索引存入哈希表中。

  3. 接着,遍历第二个列表list2,对于每个餐厅名字,检查它是否在哈希表中存在,如果存在,则计算索引和(该餐厅在list1中的索引加上在list2中的索引)。

  4. 我们需要找到最小的索引和,因此我们可以维护一个变量来记录当前的最小索引和,并在遍历过程中更新它。

  5. 如果找到一个更小的索引和,我们就更新结果列表;如果找到一个与当前最小索引和相同的索引和,则将该餐厅添加到结果列表中。

  6. 最后,返回结果列表。

三、具体代码

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<>();

        // 遍历list2
        for (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)。

  • addclear方法在ArrayList中的时间复杂度都是O(1)。

综上所述,总的时间复杂度是O(n + m),因为两个循环是独立的,我们只需将它们的时间复杂度相加。

2. 空间复杂度
  • indexMap是一个哈希表,用于存储list1中所有餐厅名字及其索引。在最坏的情况下,如果list1中的每个元素都是唯一的,那么indexMap将包含n个条目。因此,空间复杂度是O(n)。

  • result是一个列表,用于存储共同喜爱的餐厅。在最坏的情况下,如果list1list2完全相同,那么result将包含所有n个餐厅。因此,空间复杂度是O(n)。

综上所述,总的空间复杂度是O(n),因为indexMapresult是独立的数据结构,且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:用于从方法中返回值。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值