题目
给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
解题方法
两个数组的交集就是看有多少个相同的数,例如第一组例子,nums1中有两个2,同样的nums2中也有两个2,这就是两个数组的交集,毕竟数组里面可以存在相同值得元素。
哈希表
对于哈希表,首先建立一个key-value的键值对的关系,在哈希表内键是不可以重复的,所以把key设置为数组的元素的值,value对应值的个数,例如数组中1的个数有两个,键值对就是<1,2>。
遍历第一个数组,并把元素全部添加到哈希表内。然后对第二个数组进行遍历,当有元素值相同时,则添加到额外创建的结果数组当中,并把元素个数减一,直至该元素个数为零,之后再有相同元素的值,则不添加到结果数组中。
例如,遍历第二个数组中第一个1时,判断哈希表内是否存在key为1的,存在,就把对应的value减一,表示与第一个数组里面的一个1与第二个数组的一个1重合。当再次向第二个数组的第二个1遍历时,再去哈希表内对应的key的value查看第一个数组内部是否还有1的个数与之对应,如果此时value为零则不添加,否之,添加。直至对第二个数组遍历完成。
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
int[] res = new int[nums1.length];
Map<Integer, Integer> hashmap = new HashMap<>();
for (int num : nums1) {
if (hashmap.containsKey(num)){
int temp = hashmap.get(num);
hashmap.put(num, temp+1);
}else {
hashmap.put(num, 1);
}
}
int count = 0;//记录重合的元素
for(int num : nums2){
if (hashmap.containsKey(num) && (hashmap.get(num) > 0)){
res[count] = num;
count++;
int temp = hashmap.get(num);
hashmap.put(num, temp-1);
}
}
return Arrays.copyOfRange(res,0,count);//对数组的一个操作,即把对应数组的对应范围的元素复制到新的数组内,返回的是一个数组
}
}
排序 + 双指针
这个方法得思路就是对数组从小到大或者从大到小排序,本题解题代码从小到大排序,然后同时对数组遍历,并判断是否相等,当俩个指针对应的数相等,添加到结果数组内,并指针后移;当不同时,根据你得数组排序来决定哪一个指针后移,当从小到大排序时,对应值小的后移;反之,大的后移。最后返回对应数组即可。
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
int[] res = new int[nums1.length];
Arrays.sort(nums1);
Arrays.sort(nums2);
int temp1 = 0, temp2 = 0, count = 0;
while((temp1 < nums1.length) && (temp2 < nums2.length)){
if(nums1[temp1] == nums2[temp2]){
res[count] = nums1[temp1];
count++;
temp1++;
temp2++;
}else if (nums1[temp1] > nums2[temp2]){
temp2++;
}else{
temp1++;
}
}
return Arrays.copyOfRange(res,0,count);
}
}