题目及测试用例
package pid350;
/*两个数组的交集 II
给定两个数组,写一个方法来计算它们的交集。
例如:
给定 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2, 2].
注意:
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。
跟进:
如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
如果nums2的元素存储在磁盘上,内存是有限的,你不能一次加载所有的元素到内存中,你该怎么办?
*/
public class main {
public static void main(String[] args) {
int[][] testTable = {{1,1,2},{1,1,2,2,5,6,7,7},{1,2,3,5},{1,1,1,1}};
test(testTable[0],testTable[1]);
test(testTable[2],testTable[3]);
}
private static void test(int[] ito1,int[] ito2) {
Solution solution = new Solution();
int[] rtn;
long begin = System.currentTimeMillis();
for (int i = 0; i < ito1.length; i++) {
System.out.print(ito1[i]+" ");
}//开始时打印数组
System.out.println();
for (int i = 0; i < ito2.length; i++) {
System.out.print(ito2[i]+" ");
}//开始时打印数组
rtn = solution.intersect(ito1,ito2);//执行程序
long end = System.currentTimeMillis();
System.out.println("rtn=" );
for (int i = 0; i < rtn.length; i++) {
System.out.print(rtn[i]+" ");
}//打印结果几数组
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功,8ms,有点慢)
通过map数据结构解决问题
首先,将nums1 数组中的元素 转为map1 的元素 key为数组中的数,对应的value为数的个数
然后,将nums2 数组中的元素与map1的元素作对比
如果map1中有,则map1的value-1,对应的,map2的value+1
最后将map2塞入list,再转为数组
package pid350;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
HashMap<Integer, Integer> map1=new HashMap<Integer, Integer>();
//map1是nums1所有的元素填进去的map
HashMap<Integer, Integer> map2=new HashMap<Integer, Integer>();
//map2是nums 1 2 重叠的map
for(int i=0;i<nums1.length;i++){
Integer now=(Integer)nums1[i];
if(map1.containsKey(now)){
map1.put(now, map1.get(now)+1);
}
else{
map1.put(now,1);
}
}
for(int i=0;i<nums2.length;i++){
Integer now=(Integer)nums2[i];
if(map1.containsKey(now)){
map1.put(now, map1.get(now)-1);
if(map1.get(now)==0){
map1.remove(now);
}
if(map2.containsKey(now)){
map2.put(now, map2.get(now)+1);
}
else{
map2.put(now,1);
}
}
}
List<Integer> resultList=new ArrayList<Integer>();
for(Integer key:map2.keySet()){
for(int i=0;i<map2.get(key);i++){
resultList.add(key);
}
}
int[] result=new int[resultList.size()];
for (int i=0;i<result.length;i++){
result[i]=resultList.get(i);
}
return result;
}
}
解法2(别人的,成功,5ms,比较快)
这个解法思路与上一个一样,不过做了优化
1判断map的key是否为空做的很好
2 最后直接把结果加入list而不是先加入map再加入lsit
public class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Map<Integer, Integer> map1 = new HashMap<>();
for(int num: nums1) {
Integer count = map1.get(num);
if (count == null) count = 1; else count ++;
map1.put(num, count);
}
List<Integer> list2 = new ArrayList<>();
for(int num: nums2) {
Integer count = map1.get(num);
if (count == null) continue;
list2.add(num);
count --;
if (count == 0) map1.remove(num); else map1.put(num, count);
}
int[] result = new int[list2.size()];
for(int i=0; i<list2.size(); i++) result[i] = list2.get(i);
return result;
}
}
解法3(别人的,3ms,很快)
采用排序的算法,先用array的方法排序,再逐个比较,放入list
速度比之前快,主要是如果一方的长度很小,可以很快算完
public class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
List<Integer> list = new ArrayList<>();
int i=0, j=0;
while (i<nums1.length && j<nums2.length) {
if (nums1[i] == nums2[j]) { list.add(nums1[i]); i++; j++; }
else if (nums1[i] < nums2[j]) i++;
else j++;
}
int[] result = new int[list.size()];
for(int k=0; k<list.size(); k++) result[k] = list.get(k);
return result;
}
}