349. Intersection of Two Arrays

349. Intersection of Two Arrays

1. 题目
349. Intersection of Two Arrays

Given two arrays, write a function to compute their intersection.
Example 1:
Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2]
Example 2:
Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [9,4]
Note:
Each element in the result must be unique.
The result can be in any order.

2. 题目分析
求,两个数组的交集,因为结果是集合,所以必须保证结果集中元素的唯一性,如题目中的例1。另外这题与718. Maximum Length of Repeated Subarray求两个数组的最大连续公共子数组不一样的地方,在于,两个数组的交集不要连续的,但,两题都是找两个数组的公共元素。

3. 解题思路
两种解决方案:

  • 一种暴力破解的方法是,两层for循环,用nums1的每个元素遍历nums2中的所有元素,找到是否相同的元素。时间复杂度为O(n2);明显,能解决问题,但效率太低。
  • 两一种,是通过先将两个数组排序,然后转化成392. Is Subsequence的解法。即用两个指针,分别指向两个数组中遍历的位置,然后比较两则元素是否相同?
    1. 相同,因为可能存在重复元素,所以需要比较当前找到的公共元素是否与已找的交集的前一个元素是否相同,如果相同,则说明重复了,不需要添加。然后两个指针都往后移动;
    2. 如果nums1小于nums2,则只要移动nums1的指针;
    3. 如果nums1大于nums2,则只要移动nums2的指针;

补充:
一开始用来存储结果集的数据结构是ArrayList,原因是,由于我不能确定两个数组的交集的元素个数,如果使用数组开辟的空间更多的话,多出来的空间的每个默认值为0。这样其实与真正的交集不一样。如交集result={1,2},但如果我开辟的空间为4,则commons[4]={1,2,0,0},就会报错,解决方案是最后重新遍历commons集合,把有用的元素放到一个新的结果集中,但这样多了一个for循环,即多加了O(n)。所以我用动态扩容的list数组,提交后我发现,处理效率会明显小于使用数组的效率。另外,参考答案的时候,原来可以直接使用jdk的api方法,Arrays.copyOf(commonSection,count),实现其实是调用System.arraycopy(),这个方法是native方法,网上说是对数组内存进行复制,效率明显会比for循环快。

4. 代码实现(java)

package com.algorithm.leetcode.binarySearch;

import java.util.Arrays;

/**
 * Created by 凌 on 2019/2/8.
 * 注释:349. Intersection of Two Arrays
 */
public class Intersection {
    public static void main(String[] args) {
        int[] nums1={1,2,2,1};
        int[] nums2={2,2};
        int[] commonSection =intersection(nums1,nums2);
        for (int i = 0; i < commonSection.length; i++) {
            System.out.printf(commonSection[i]+"\t");
        }
    }

    public static int[] intersection(int[] nums1, int[] nums2) {
        if (nums1==null || nums2==null){
            return null;
        }

        /*List<Integer> commonSection = new ArrayList<>();
        int count1=0;
        int count2=0;
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        while (count1 < nums1.length && count2 < nums2.length){
            if (nums1[count1] == nums2[count2]){
                if (commonSection.size()>0 && commonSection.get(commonSection.size()-1) == nums1[count1]){
                    count1++;
                    count2++;
                }else{
                    commonSection.add(nums1[count1]);
                }
            }else if (nums1[count1] < nums2[count2]){
                count1++;
            }else {
                count2++;
            }
        }
        int[] result = new int[commonSection.size()];
        int count=0;
        for (Integer value:commonSection){
            result[count++]=value;
        }
        return result;*/
        int len = nums1.length > nums2.length?nums2.length:nums1.length;
        int[] commonSection=new int[len];
        int count1=0;
        int count2=0;
        int count=0;
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        while (count1 < nums1.length && count2 < nums2.length){
            if (nums1[count1] == nums2[count2]){
                if (count > 0 && commonSection[count-1] == nums1[count1]){
                    count1++;
                    count2++;
                }else{
                    commonSection[count++]=nums1[count1];
                }
            }else if (nums1[count1] < nums2[count2]){
                count1++;
            }else {
                count2++;
            }
        }

        return Arrays.copyOf(commonSection,count);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值