leetcode 刷题(84)——350.两个数组的交集 II

一、题目

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]

示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]

说明:

  • 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
  • 我们可以不考虑输出结果的顺序。

二、思路及代码实现

思路一:哈希映射

  • 统计一个数组中每个数字出现的次数,存放在 HashMap 中(以 值-出现次数 的形式存储);
  • 遍历另一个数组,查找每个数字是否存在哈希表中,如果存在,将该数字添加至结果集,并把 hashMap 中对应的次数减一;如果不存在,则检查下一个数字。

代码实现(一):

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int i : nums1){
            if(map.containsKey(i))
                map.put(i, map.get(i) + 1);
            else
                map.put(i, 1);
        }
        int k = 0;
        for(int n : nums2){
            if(map.containsKey(n) && map.get(n) > 0){
                nums1[k++] = n;
                map.put(n, map.get(n) - 1);
            }
        }
        return Arrays.copyOfRange(nums1, 0, k);
    }
}

利用 Map 的 getOrDefault() 方法,可以简化代码。

Map 的 getOrDefault(key, defaultValue) 方法:

  • 括号中的第一个参数是你要取的 key,第二个参数是你指定的默认值;
  • 意思是:如果 map 中存在 key 这个键,那就返回这个键对应的值;不存在这个 key,则返回默认值。

举个例子:

Map<Integer, Integer> map = new HashMap<>();
map.put(1, 11);

// 存在 1 这个键,返回其对应的值 11
System.out.println(map.getOrDefault(1, 22)); // 11
// 不存在 3 这个键,返回默认值 33
System.out.println(map.getOrDefault(3, 33)); // 33

// 需要注意的是:
// 		只要存在这个 key,就返回它对应的值,即使这个值为 null;不存在这个 key 时,才返回默认值。
map.put(4, null);
// 这里打印的是 null,而不是 22
System.out.println(map.getOrDefault(4, 22));

简化代码如下:

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int i : nums1){
            int count = map.getOrDefault(i, 0);
            map.put(i, count + 1);
        }
        int k = 0;
        for(int n : nums2){
            int t = map.getOrDefault(n, 0);
            if(t > 0){
                nums1[k++] = n;
                map.put(n, t - 1);
            }
        }
        return Arrays.copyOfRange(nums1, 0, k);
    }
}

思路二:排序

分别对两个数组进行排序,然后逐个比对两个数组的元素,找到重复元素。

  • 对两个数组排序;
  • 初始化三个指针 i = 0、j = 0、k = 0,i 和 j 指向两个数组,k 用来记录重复元素的个数;
    • 如果 n u m s 1 [ i ] = n u m s 2 [ j ] nums1[i] = nums2[j] nums1[i]=nums2[j],将该元素拷贝到 n u m s 1 [ k ] nums1[k] nums1[k],然后 i++,j++,k++;
    • 如果 n u m s 1 [ i ] > n u m s 2 [ j ] nums1[i] > nums2[j] nums1[i]>nums2[j],j++;
    • 如果 n u m s 1 [ i ] < n u m s 2 [ j ] nums1[i] < nums2[j] nums1[i]<nums2[j],i++。
  • 最后返回 nums1 的前 k 个元素。

代码如下:

class Solution {
    public int[] intersect(int[] nums1, int[] nums2){
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int i = 0, j = 0, k = 0;
        while(i < nums1.length && j < nums2.length){
            if(nums1[i] == nums2[j]){
                nums1[k] = nums2[j];
                i++;
                j++;
                k++;
            }else if(nums1[i] > nums2[j]){
                j++;
            }else if(nums1[i] < nums2[j]){
                i++;
            }
        }
        return Arrays.copyOfRange(nums1, 0, k);
    }
}

你可能感兴趣的:(leetcode刷题)