599. Minimum Index Sum of Two Lists
Problem statement:
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:
- The length of both lists will be in the range of [1, 1000].
- The length of strings in both lists will be in the range of [1, 30].
- The index is starting from 0 to the list length minus 1.
- No duplicates in both lists.
Solution one: hash table + heap
This is the second problem of leetcode weekly contest 34. We need data structures to solve it. We should return the minimal index sum for common interests. There is two work for us to do.
- Find the common interests. ---> hash table(unordered_map)
- Find the min index sum among all common interests. ---> heap(priority_queue).
We should do some change on the heapsort function to return the minimal index sum
Time complexity:
- Loop for this two string lists: O(l1 + l2)
- Loop for the heap to find the minimal index sum. Since the time complexity to reheapify after one element is popped from the heap is O(klgk). k is the number of common interests.
Time complexity is O(l1 + l2) + O(klgk).
Space complexity is O(l1 + k).
class Solution { public: vector<string> findRestaurant(vector<string>& list1, vector<string>& list2) { auto comp = [](pair<int, string>& left, pair<int, string>& right){ return left.first > right.first; }; priority_queue<pair<int, string>, vector<pair<int, string>>, decltype(comp)> pq(comp); unordered_map<string, int> hash_table; // <"restaurant", index_sum> for(int i = 0; i < list1.size(); i++){ hash_table[list1[i]] = i; } for(int i = 0; i < list2.size(); i++){ if(hash_table.count(list2[i])){ pq.push({hash_table[list2[i]] + i, list2[i]}); } } vector<string> common_interests; int min_idx = pq.top().first; while(!pq.empty()){ if(pq.top().first == min_idx){ common_interests.push_back(pq.top().second); pq.pop(); } else { break; } } return common_interests; } };
Solution two: two hash tables
- Loop the first list and insert each element into the hash table index by the name of a restaurant.
- Loop the second list, if the current restaurant is a common interest and the index sum of them is:
- less than the current value, create a new item in the second hash table indexed by the index sum.
- equal to current value, push back to the solution.
Time complexity is O(l1 + l2).
Space complexity is O(l1 + k).
class Solution { public: vector<string> findRestaurant(vector<string>& list1, vector<string>& list2) { unordered_map<string, int> hash_table; // <string, index> for(int i = 0; i < list1.size(); i++){ hash_table[list1[i]] = i; } unordered_map<int, vector<string>> common_interests; int min_common = INT_MAX; string restaurant_name; for(int j = 0; j < list2.size(); j++){ if(hash_table.count(list2[j])){ if(hash_table[list2[j]] + j <= min_common){ min_common = hash_table[list2[j]] + j; restaurant_name = list2[j]; common_interests[min_common].push_back(restaurant_name); } } } return common_interests[min_common]; } };
599. Minimum Index Sum of Two Lists