返回

揭开LeetCode打卡day14的神秘面纱:巧解599. 两个列表的最小索引总和

前端

前言

LeetCode打卡,日日精进! 在LeetCode打卡day14中,我们聚焦于一道颇具技术挑战性的算法题目——599. 两个列表的最小索引总和。这道题考验了我们对动态规划和哈希表的理解,要求我们找出两个列表中的元素,使得它们在各自列表中的索引之和最小。

题目

假设 Andy 和 Doris 想在晚餐时选择一家餐馆。他们分别有自己的餐馆喜好列表,其中包含他们最喜欢的餐馆名称。现在,他们想知道,在两个列表中都存在的一家餐馆,其在两个列表中的索引之和最小是多少。如果有多家这样的餐馆,请返回其中索引和最小的餐馆名称。

示例:

输入:list1 = ["Shogun", "Tapioca Express", "Burger King", "KFC"], list2 = ["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"]
输出:"Shogun"
解释:两家餐馆都在两个列表中,且它们的索引之和最小,为 1 (0 + 1)。

解题思路

解决这道题目的关键在于寻找一个既能满足约束条件,又能最小化索引总和的餐馆。有两种常见的方法可以实现这一目标:

动态规划:

动态规划算法通过构建一个表格来解决问题,其中每个单元格表示在考虑前 i 个餐馆时,Andy 和 Doris 在两个列表中找到的索引和最小的餐馆名称。该算法的时间复杂度为 O(mn),其中 m 和 n 分别是两个列表的长度。

哈希表:

哈希表是一种数据结构,允许我们根据键值快速查找和检索元素。我们可以使用一个哈希表来存储第一个列表中的餐馆名称,然后遍历第二个列表,查找存在于哈希表中的餐馆。这种方法的时间复杂度为 O(m + n),其中 m 和 n 分别是两个列表的长度。

代码实现

动态规划:

class Solution {
    public String findRestaurant(String[] list1, String[] list2) {
        int m = list1.length, n = list2.length;
        int[][] dp = new int[m + 1][n + 1];
        String res = "";
        int minSum = Integer.MAX_VALUE;

        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n; j++) {
                if (i == 0 || j == 0) {
                    dp[i][j] = Integer.MAX_VALUE;
                } else if (list1[i - 1].equals(list2[j - 1])) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    if (dp[i][j] < minSum) {
                        minSum = dp[i][j];
                        res = list1[i - 1];
                    }
                } else {
                    dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + 1;
                }
            }
        }

        return res;
    }
}

哈希表:

class Solution {
    public String findRestaurant(String[] list1, String[] list2) {
        int m = list1.length, n = list2.length;
        Map<String, Integer> map = new HashMap<>();
        String res = "";
        int minSum = Integer.MAX_VALUE;

        for (int i = 0; i < m; i++) {
            map.put(list1[i], i);
        }

        for (int i = 0; i < n; i++) {
            if (map.containsKey(list2[i])) {
                int sum = map.get(list2[i]) + i;
                if (sum < minSum) {
                    minSum = sum;
                    res = list2[i];
                }
            }
        }

        return res;
    }
}

总结

通过解决 LeetCode打卡day14 中的 599. 两个列表的最小索引总和,我们巩固了对动态规划和哈希表的理解。这道题目不仅考验了我们的算法技能,还让我们领悟了如何在不同的约束条件下找到最优解。希望本文能够帮助你提升自己的 LeetCode 解题能力,继续在算法的世界中探索和精进!