LeetCode 350--兩個數組的交集 II --數組--簡單

https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/submissions/ 

 解題思路:

1、哈希表

1)一個數組 創建爲哈希表, 記錄鍵:元素  值:元素出現的次數

2)另一個數組利用O(1)時間查找,若出現則次數減去1

3)輸出新結果放入數組內

//C++
class Solution {
public:
  vector<int> intersect(vector<int>& nums1, vector<int>& nums2) 
  {
    if (nums1.size() > nums2.size()) 
    {
        return intersect(nums2, nums1);//交換,數組元素較少的用於創建哈希表
    }
    unordered_map<int, int> m;
    for (auto n : nums1)
    {
        ++m[n];
    }
    int k = 0;
    for (auto n : nums2) {
        auto it = m.find(n);//尋找元素對應的迭代器
        if (it != end(m) && --it->second >= 0) //value值也即是計數值大於等於0(注意還有等於號,不然出錯) https://blog.csdn.net/tcx1992/article/details/80928790
        {
            nums1[k++] = n;//覆蓋nums1沒有再用到
        }
    }
    return vector(begin(nums1), begin(nums1) + k);
  }
};

注意上述等同於--(it->second)>=0 

 unordered_map是一個關聯容器:

map可以鍵值是有序的,而 unordered_map鍵值順序可變

創建:

 unordered_map<int, int> m;表示創建第一個鍵爲int型,第二個值爲int型

方法:

begin():指向第一個元素

end():指向最後一個元素之後的位置

find():如果鍵在map中找不到則返回最後一個元素的下一個位置

 it->first指向鍵 ,it->second指向值 

參考:https://www.geeksforgeeks.org/unordered_map-in-cpp-stl/

//Java
class Solution {
   public int[] intersect(int[] nums1, int[] nums2) 
   {
    if (nums1.length > nums2.length) 
    {
        return intersect(nums2, nums1);
    }
    HashMap<Integer, Integer> m = new HashMap<>();
    for (int n : nums1) 
    {
        m.put(n, m.getOrDefault(n, 0) + 1);
    }
    int k = 0;
    for (int n : nums2) 
    {
        int cnt = m.getOrDefault(n, 0);
        if (cnt > 0) 
        {
            nums1[k++] = n;
            m.put(n, cnt - 1);
        }
    }
    return Arrays.copyOfRange(nums1, 0, k);
}
}

HashMap-Java

創建:

HashMap<Integer, Integer> m = new HashMap<>();

鍵唯一,值可以不唯一

方法:

getOrDefault(Object key, V defaultValue):返回key對應的value值,若找不到則使用默認值defaultValue

Object put(Object key, Object value):插入鍵值對

Object get(Object key): 檢索或獲取指定鍵對應的值

參考:https://www.geeksforgeeks.org/java-util-hashmap-in-java-with-examples/

public static int[] copyOfRange(int[] original_array, int from_index, int to_index):創建原始數據的副本,指向從from_index到to_index

參考:https://www.geeksforgeeks.org/java-util-arrays-copyofrange-java/

算法複雜度分析:

時間複雜度:O(n+m)

空間複雜度:O(min(n,m))

如果給定的數組已經排好序呢?你將如何優化你的算法?

2、使用雙指針

1)兩個數組先排序
2)定義雙指針,分別指向兩個數組首位置,若相等則輸出,若num1(i)<num2(j) 則i++  否則j++
//C++
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2)
{
    sort(begin(nums1), end(nums1));//排序
    sort(begin(nums2), end(nums2));
    int i = 0, j = 0, k = 0;
    while (i < nums1.size() && j < nums2.size()) 
    {
        if (nums1[i] < nums2[j]) 
        {
            ++i;
        } else if (nums1[i] > nums2[j]) 
        {
            ++j;
        } else 
        {
            nums1[k++] = nums1[i++];
            ++j;
        }
    }
    return vector<int>(begin(nums1), begin(nums1) + k);
}
};
//java
class Solution {
   public int[] intersect(int[] nums1, int[] nums2) 
   {
    Arrays.sort(nums1);
    Arrays.sort(nums2);
    int i = 0, j = 0, k = 0;
    while (i < nums1.length && j < nums2.length) 
    {
        if (nums1[i] < nums2[j])
        {
            ++i;
        }
        else if (nums1[i] > nums2[j]) 
        {
            ++j;
        } 
        else 
        {
            nums1[k++] = nums1[i++];
            ++j;
        }
    }
    return Arrays.copyOfRange(nums1, 0, k);
}
}

算法複雜度分析:

時間複雜度:O(n+logn+m+logm) ?排序時間+ while (i < nums1.length && j < nums2.length) 運行的次數

空間複雜度:O(1)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章