349.Given two arrays, write a function to compute their intersection.
Example:
Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2].
Note:
Each element in the result must be unique.
其实就是求两个数组的公共子集。
思路一:使用两个HashSet,一个用于存储结果,另一个用于将其中一个数组转化为集合,方便查询一个数是否存在于该集合中。
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> res = new HashSet<Integer>();
Set<Integer> tmp = new HashSet<Integer>();
int n1 = nums1.length;
int n2 = nums2.length;
if(n1>n2)
{
for(int nn:nums1)
tmp.add(nn);
for(int i=0; i<n2; i++)
if(tmp.contains(nums2[i]))
res.add(nums2[i]);
}
else
{
for(int nn:nums2)
tmp.add(nn);
for(int i=0; i<n1; i++)
if(tmp.contains(nums1[i]))
res.add(nums1[i]);
}
int [] rest = new int[res.size()];
int i = 0;
for(int aa:res)
rest[i++] = aa;
return rest;
}
思路二:使用二叉查询来代替哈希集合,实现查询功能。
public int[] intersection2(int[] nums1, int[] nums2)
{
Set<Integer> res = new HashSet<Integer>();
Arrays.sort(nums2);
for(Integer num :nums2)
if(binarySearch(nums2,num))
res.add(num);
int[] result = new int[res.size()];
int k = 0;
for (Integer num : res) {
result[k++] = num;
}
return result;
}
public boolean binarySearch(int[] nums, int target)
{
int low = 0;
int high = nums.length-1;
while(low<=high)
{
int mid = low + (low+high)/2;
if(nums[mid] == target)
return true;
else if(nums[mid] > target)
high = mid-1;
else
low = mid + 1;
}
return false;
}
思路三:将两个数组排序,然后使用指针进行比较元素大小,逐步移动。
public int[] intersection1(int[] nums1, int[] nums2) {
Set<Integer> set = new HashSet<Integer>();
Arrays.sort(nums1);
Arrays.sort(nums2);
int i = 0;
int j = 0;
while (i < nums1.length && j < nums2.length) {
if (nums1[i] < nums2[j]) {
i++;
} else if (nums1[i] > nums2[j]) {
j++;
} else {
set.add(nums1[i]);
i++;
j++;
}
}
int[] result = new int[set.size()];
int k = 0;
for (Integer num : set) {
result[k++] = num;
}
return result;
}
350.Given two arrays, write a function to compute their intersection.
Example:
Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2].
Note:
Each element in the result should appear as many times as it shows in both arrays.
The result can be in any order.
相比上一题,增加了结果中元素可重复的条件。所以在这里使用列表作为存储结果的数据结构,使其中元素可以重复。
public int[] intersect(int[] nums1, int[] nums2) {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
ArrayList<Integer> result = new ArrayList<Integer>();
for(int i = 0; i < nums1.length; i++)
{
if(map.containsKey(nums1[i])) map.put(nums1[i], map.get(nums1[i])+1);
else map.put(nums1[i], 1);
}
for(int i = 0; i < nums2.length; i++)
{
if(map.containsKey(nums2[i]) && map.get(nums2[i]) > 0)
{
result.add(nums2[i]);
map.put(nums2[i], map.get(nums2[i])-1);
}
}
int[] r = new int[result.size()];
for(int i = 0; i < result.size(); i++)
{
r[i] = result.get(i);
}
return r;
}
同样可以现将两个数组先进行排序,然后使用两个指针进行便利两个数组的方法,跟上面一样,不过使用列表作为存储的数据结构即可。