350. Intersection of Two Arrays II

来源:互联网 发布:动画创意广告软件 编辑:程序博客网 时间:2024/06/04 19:14

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.
Follow up:
What if the given array is already sorted? How would you optimize your algorithm?
What if nums1’s size is small compared to nums2’s size? Which algorithm is better?
What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?
Subscribe to see which companies asked this question

本人的测试用例:

Solution s = new Solution();    @Test    public void intersectTest(){//      int[] nums1 = new int[]{1, 2, 2, 1};//      int[] nums2 = new int[]{2, 2};        int[] nums1 = new int[]{1};        int[] nums2 = new int[]{1,1};        int[] nums = s.intersect(nums1, nums2);        Util.printArray(nums);    }

方法一:

思路:

  1. 分别统计出数组nums1,nums2的每个数字出现的次数,并保存到map1,map2中;
  2. 循环遍历map1,map2 。比较map1中出现的数字key是否出现在map2中,如果出现,比较map1中该数字出现的次数和map2中出现的次数,取小的次数smallCount,并在list中添加smallCount次key.如果没有出现,继续循环。

代码:

public int[] intersect1(int[] nums1, int[] nums2) {        List<Integer> list = new ArrayList<>();        if (nums1 == null || nums2 == null)            return new int[0];        if (nums1.length == 0 || nums2.length == 0)            return new int[0];        Map<Integer, Integer> map1 = new HashMap<>();        Map<Integer, Integer> map2 = new HashMap<>();        for (int i = 0; i < nums1.length; i++) {            if (map1.get(nums1[i]) == null) {                map1.put(nums1[i], 1);            } else {                map1.put(nums1[i], map1.get(nums1[i]) + 1);            }        }        for (int i = 0; i < nums2.length; i++) {            if (map2.get(nums2[i]) == null) {                map2.put(nums2[i], 1);            } else {                map2.put(nums2[i], map2.get(nums2[i]) + 1);            }        }        for (Map.Entry<Integer, Integer> en : map1.entrySet()) {            int key = en.getKey();            int smallCount = 0;            if (map2.containsKey(key)) {                smallCount = en.getValue() > map2.get(key) ? map2.get(key) : en.getValue();            }            while (smallCount > 0) {                list.add(key);                smallCount--;            }        }        int[] result = new int[list.size()];        for (int i = 0; i < list.size(); i++) {            result[i] = list.get(i);        }        return result;    }

方法二:

思路:

  1. 先将nums1,nums2排序;
  2. 循环遍历nums1,nums2。并对nums1,nums2分别使用i,j双指针,比较nums1[i] 和nums2[j]的大小关系。如果相等两个指针同时向前移动一位。如果不相等将较小者的指针,向前移动一位。

代码:

    public int[] intersect(int[] nums1, int[] nums2) {        List<Integer> list = new ArrayList<>();        if (nums1 == null || nums2 == null)            return new int[0];        if (nums1.length == 0 || nums2.length == 0)            return new int[0];        Arrays.sort(nums1);        Arrays.sort(nums2);        int i = 0;        int j = 0;        while(i<nums1.length && j<nums2.length){            if(nums1[i]>nums2[j]){                j++;            }else if(nums1[i] <nums2[j]){                i++;            }else{                list.add(nums1[i]);                i++;                j++;            }        }        int[] result = new int[list.size()];        for ( i = 0; i < list.size(); i++) {            result[i] = list.get(i);        }        return result;    }

总结:

这个题看似简单,就上手写了两次都没有成功。之后想到使用了方法一。但从网上看了方法二的解法,就自己有写了一遍,感觉更加精妙。以后还是要巧妙地使用双指针。

0 0
原创粉丝点击