每日一题:两个数组的交集|

196 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情

题目链接

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序

示例 1:

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

示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

提示:

1 <= nums1.length, nums2.length <= 1000

0 <= nums1[i], nums2[i] <= 1000

解题思路(二分查找)

这道题我们可以使用二分查找来实现

题目中要求我们输出结果中的每个元素一定是唯一的,我们可以使用集合set,因为集合set是一个不允许有重复元素的集合,我们可以利用这个特性,用集合set来存储数组的交集,最后再转换为数组

具体思路:

  1. 先将 nums2 排序
  2. 遍历 nums1,查找 nums1nums2 共有的元素,再用 集合setcontains 方法去判断 集合set 里 是否有存放这个元素,起到去重作用

代码:(JAVA实现)

   public int[] intersection(int[] nums1, int[] nums2) {
        if (nums1.length == 0 || nums2.length == 0 || nums1 == null || nums2 == null) {
            return new int[0];
        }
        HashSet<Integer> set = new HashSet<>();
        Arrays.sort(nums2);

        for (int i : nums1) {
            //当nums1 和 nums2 中有共同的元素 且 集合set 中没有这个元素这两个条件都满足时
            //集合set 里才会将这个元素添加到集合里去
            if (find(nums2,i) && !set.contains(i)) {
                set.add(i);
            }
        }
        
        //添加完后,要把集合里的元素遍历放进数组里,数组的长度就是集合的元素个数
        int[] ints = new int[set.size()];
        int index = 0;
        for (int i : set) {
            ints[index] = i;
            index++;
        }
   
        return ints;
    }
    
    //这个方法就是为了查找 nums1 和 nums2 中是否有共有的元素
    public static boolean find(int[] nums,int target) {
        int left = 0;
        int right = nums.length-1;
        while (left <= right) {
            int mid = left + (right - left)/2;
            if (nums[mid] == target) {
                return true;
            }else if (nums[mid] > target) {
                right = mid - 1;
            }else {
                left = mid + 1;
            }
        }
        return false;
    }

时间复杂度:O(log n)

空间复杂度:O(1)

提交结果

image.png

解题思路:(哈希表)

从提交结果可以看出,二分查找虽然也能提交成功,但复杂度也不低,并不是最优解

所以本题还可以使用一种方法,Set来做这道题

具体思路:

  1. 思路跟上面的二分很像,也是先排序 nums2
  2. 定义两个集合set,给它们分别起名set1set2
  3. nums1 遍历,把里面的元素都放进 set1 里去
  4. 再遍历 nums2 ,把 set1nums2共有的元素添加进 set2,因为 集合set 是个没有重复元素的集合 ,所以我们不用担心 set2 中有重复的元素
  5. set2 遍历,把里面的元素添加到新的数组里,返回数组

代码:(JAVA实现)

public int[] intersection(int[] nums1, int[] nums2) {
        if (nums1.length == 0 || nums2.length == 0 || nums1 == null || nums2 == null){
            return new int[0];
        }

        HashSet<Integer> set1 = new HashSet<>();
        HashSet<Integer> set2 = new HashSet<>();

        for (int i : nums1) {
            set1.add(i);
        }
           
        for (int i : nums2) {
            if (set1.contains(i)) {
                set2.add(i);
            }
        }

        int[] num = new int[set2.size()];
        int j = 0;
        for (int i : set2) {
            num[j] = i;
            j++;
        }
        return num;
    }

时间复杂度:O(1)

空间复杂度:O(1)

提交结果

image.png