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、使用雙指針
//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)