查找兩鏈表中節點元素相同的下標之和最小 Minimum Index Sum of Two Lists

問題:api

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.ui

Example 1:spa

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:rest

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:rem

  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.

【注意】最小下標值是指在兩個數組中的下標之和最小。字符串

解決: get

① 使用map保存list1中的單詞,鍵---單詞,值---數組下標。在遍歷list2時,計算最小的下標和,使用list保存最小下標和所對應的單詞。耗時30ms.string

public class Solution {
    public String[] findRestaurant(String[] list1, String[] list2) {
        List<String> list = new ArrayList<>();
        Map<String,Integer> map = new HashMap<>();    
        for (int i = 0;i < list1.length;i ++) {//鍵---單詞,值---數組下標
            map.put(list1[i],i);
        }
        int tmp = 0;
        int minSum = Integer.MAX_VALUE;
        for(int i = 0;i < list2.length;i ++){
            if (map.containsKey(list2[i])) {//若相等
                tmp = map.get(list2[i]);
                if(i + tmp < minSum){//下標和最小
                    minSum = i + tmp;
                    list.clear();
                    list.add(list2[i]);
                }else if(i + tmp == minSum){//最小下標和相等
                    list.add(list2[i]);
                }
            }
        }
        return list.toArray(new String[list.size()]);
    }
}hash

②另外一種使用hash map 的方法,鍵---兩下標之和,值---相同的字符串所構成的list,這樣全部相同的字符串都被保存到了hash map中,只需遍歷該map,找到下標和最小的便可。這種方法時間複雜度最大O(n^2),不建議採用這種方法。

public class Solution {
    public String[] findRestaurant(String[] list1, String[] list2) {
        HashMap < Integer, List < String >> map = new HashMap < > ();
        for (int i = 0; i < list1.length; i++) {
            for (int j = 0; j < list2.length; j++) {
                if (list1[i].equals(list2[j])) {
                    if (!map.containsKey(i + j))
                        map.put(i + j, new ArrayList < String > ());
                    map.get(i + j).add(list1[i]);

                }
            }
        }
        int min_index_sum = Integer.MAX_VALUE;
        for (int key: map.keySet())
            min_index_sum = Math.min(min_index_sum, key);
        String[] res = new String[map.get(min_index_sum).size()];
        return map.get(min_index_sum).toArray(res);
    }
}

③不使用hash map已知要找的目標是下標和最小而且兩鏈表對應的值相等,因此按照下標和由0到list1.length + list2.length - 1,這樣,遍歷鏈表中由0到sum看是否有相等的值,若知足條件就返回結果。耗時73ms。時間複雜度爲O(N^2).

public class Solution {
    public String[] findRestaurant(String[] list1, String[] list2) {
        List < String > res = new ArrayList < > ();//保存結果
        for (int sum = 0; sum < list1.length + list2.length - 1; sum ++) {             for (int i = 0; i <= sum; i ++) {                 if (i < list1.length && sum - i < list2.length && list1[i].equals(list2[sum - i]))                     res.add(list1[i]);             }             if (res.size() > 0)                 break;         }         return res.toArray(new String[res.size()]);     } }

相關文章
相關標籤/搜索