一、题目描述

二、题目思路
- hashmap可以存储 键 不重复的元素
- 存储nums1数组所有元素,遍历nums2数组所有元素,出现重复元素即添加进集合中,并更新重复元素对应的value值
三、提交代码
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
HashMap<Integer,Integer> hashMap = new HashMap<>();
for(int i =0;i<nums1.length;i++){
hashMap.put(nums1[i],hashMap.getOrDefault(nums1[i],0)+1);
}
ArrayList<Integer> list = new ArrayList<>();
for(int i=0;i<nums2.length;i++){
if(hashMap.containsKey(nums2[i])&&hashMap.get(nums2[i])>0){
list.add(nums2[i]);
hashMap.put(nums2[i],hashMap.get(nums2[i])-1);
}
}
int[] result = new int[list.size()];
for(int i =0;i<list.size();i++){
result[i] = list.get(i);
}
return result;
}
}
四、存在的问题
- 时间复杂度为O(n+m)
- 空间复杂度为O(n)
- 提交的代码中,如果n>m,则浪费多余的存储空间,因此 可以优化代码在程序开头:
if(nums1.length>nums2.length){
return intersect(nums2,nums1);
}
HashMap<Integer,Integer> hashMap = new HashMap<>();
...
五、关于进阶问题
以上解法即进阶问题二的答案
针对问题一:
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int i =0;
int j =0;
int k =0;
ArrayList<Integer> list = new ArrayList<>();
while(i<nums1.length&&j<nums2.length){
if(nums1[i]<nums2[j]){
i++;
}else if(nums1[i]>nums2[j]){
j++;
}else{
list.add(nums1[i]);
i++;
j++;
}
}
int[] result = new int[list.size()];
for(int a:list){
result[k] = a;
k++;
}
return result;
}
}
对于问题一,由于数组已经排序完成,因此可以使用两个指针进行判断,排序后的数组存在大小关系,方便对指针进行操作
时间复杂度为O(nlogn+mlogm),包括对数组进行排序,以及线性扫描
空间复杂度是O(1),主要开辟了存储答案的空间
针对问题二:
可以考虑提交代码的方法
针对问题三:
对应进阶问题三,如果内存十分小,不能使用空间复杂度高的算法
针对排序算法,一般说排序算法都是针对于内部排序,一旦涉及到跟磁盘打交道(外部排序),归并排序是天然适合外部排序的算法,可以将分割后的子数组写到单个文件中,归并时将小文件合并为更大的文件。当两个数组均排序完成生成两个大文件后,即可使用双指针遍历两个文件,如此可以使空间复杂度最低。