leetcode-599-Minimum Index Sum of Two Lists

题目描述:

Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings.

You need to help them find out their common interest with the least list index sum. If there is a choice tie between answers, output all of them with no order requirement. You could assume there always exists an answer.

Example 1:

Input:
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"]
Output: ["Shogun"]
Explanation: The only restaurant they both like is "Shogun".

 

Example 2:

Input:
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["KFC", "Shogun", "Burger King"]
Output: ["Shogun"]
Explanation: The restaurant they both like and have the least index sum is "Shogun" with index sum 1 (0+1).

 

Note:

  1. The length of both lists will be in the range of [1, 1000].
  2. The length of strings in both lists will be in the range of [1, 30].
  3. The index is starting from 0 to the list length minus 1.
  4. No duplicates in both lists.

 

要完成的函数:

vector<string> findRestaurant(vector<string>& list1, vector<string>& list2)

 

说明:

1、给定两个vector,里面分别存储两个人的喜好餐厅名字,最开始是最喜欢的,接下来其次……这样子排列下去。

要求找到两个人的共同喜好餐厅,并且要尽可能找到两个人最喜欢的。如果喜欢程度相同的话,可能会有多个餐厅名字。

2、首先,如果想要花费时间够少,我们可以增加空间复杂度,使用map来存储给定vector中的餐厅名字和餐厅的喜好顺序。

先遍历一遍第一个vector,存储所有餐厅的名称和喜好顺序在map中。接着遍历第二个vector,如果餐厅名字在map中,那么计算喜好顺序的和,存储整个过程中的最小的喜好顺序的和。

最后,再遍历一遍第二个vector,再计算一遍喜好顺序的和,如果等于这个最小值,那么存储在最终要返回的vector中。

代码如下:(附解释)

    vector<string> findRestaurant(vector<string>& list1, vector<string>& list2) 
    {
        unordered_map<string,int>m1;//使用unordered_map速度更快
        int min1=INT_MAX;
        int j,t;
        vector<string>res;
        for(int i=0;i<list1.size();i++)//存储餐厅名称和喜好顺序
            m1[list1[i]]=i;
        for(int i=0;i<list2.size();i++)
        {
            if(m1.count(list2[i])==0)//如果没有出现过,那么不是共同餐厅
                continue;
            else 
                min1=min(min1,m1[list2[i]]+i);//存储最小的喜好顺序的和
        }
        for(int i=0;i<list2.size();i++)
        {
            if(m1.count(list2[i])==0)//如果没有出现过,那么不是共同餐厅
                continue;
            else
            {
                if((m1[list2[i]]+i)==min1)//如果等于最小值,那么存储
                    res.push_back(list2[i]);
            }   
        }
        return res;
    }

上述代码十分易懂,思路也很直接,实测106ms,beats 54.32% of cpp submissions。

3、改进:

上述代码中,我们遍历了两次第二个vector,第一次遍历是计算喜好顺序之和,存储整个过程的最小值;第二次遍历是计算喜好顺序之和,如果和等于最小值,那么存入res中。

那我们可不可以只计算一次喜好顺序之和,不要做第二次重复的运算?

我们可以在遍历的过程中,依然存储和的最小值,然后碰到下一家餐厅,按照如下方法处理:

如果下一家餐厅的喜好顺序之和,大于最小值,那么跳过这家餐厅。

如果下一家餐厅的喜好顺序之和,等于最小值,那么把餐厅的名称存入res中。

如果下一家餐厅的喜好顺序之和,小于最小值,那么把当前res清空,存入当前这个餐厅的名称。

代码如下:

    vector<string> findRestaurant(vector<string>& list1, vector<string>& list2) 
    {
        vector<string>res;
        unordered_map<string,int>m1;
        int min1=INT_MAX;
        for(int i = 0; i < list1.size(); i++) 
            m1[list1[i]] = i;
        for(int i = 0; i < list2.size(); i++)
        {
            if(m1.count(list2[i]) != 0)
            {
                if(m1[list2[i]] + i < min1) 
                {
                    min1=m1[list2[i]] + i;
                    res.clear();
                    res.push_back(list2[i]);
                }   
                else if(m1[list2[i]] + i == min1) 
                    res.push_back(list2[i]);
            }
                
        }
        return res;
    }

上述代码实测92ms,beats 89.75% of cpp submissions。

原文地址:https://www.cnblogs.com/chenjx85/p/9022495.html