leetcode系列(三):Intersection of two arrays

来源:互联网 发布:结构弯矩计算软件 编辑:程序博客网 时间:2024/06/06 16:30

Intersection of two arrays

java中的一些方法的时间和空间复杂度
sort:O(nlgn)时间复杂度和O(1)空间复杂度
contains():O(1)时间复杂度

交集不能重复

O(n^2) 暴力遍历解法

  public int[] intersection(int[] nums1, int[] nums2) {        int len1=nums1.length;        int len2=nums2.length;        if(len1==0||len2==0) return new int[0];        ArrayList<Integer> result=new  ArrayList<>();        for(int i=0;i<len1;i++){            for(int j=0;j<len2;j++){                if(nums1[i]==nums2[j]){                    if(!result.contains(nums1[i])){                        result.add(nums1[i]);                    }                }            }        }        int[] resultnums=new int[result.size()];        for(int i=0;i<result.size();i++){            Integer in=(Integer)result.get(i);            int value=in.intValue();            resultnums[i]=value;        }        return resultnums;    }

此解法为O(n^2)的时间复杂度和O(n)的arraylist空间复杂度。比较naive的一种解法,也是我目前知道的解法

O(nlgn) :二分查找法

public class Solution {    public int[] intersection(int[] nums1, int[] nums2) {        Set<Integer> set = new HashSet<>();        Arrays.sort(nums2);        for (Integer num : nums1) {            if (binarySearch(nums2, num)) {                set.add(num);            }        }        int i = 0;        int[] result = new int[set.size()];        for (Integer num : set) {            result[i++] = num;        }        return result;    }    public boolean binarySearch(int[] nums, int target) {        int low = 0;        int high = nums.length - 1;        while (low <= high) {            int mid = low + (high - low) / 2;            if (nums[mid] == target) {                return true;            }            if (nums[mid] > target) {                high = mid - 1;            } else {                low = mid + 1;            }        }        return false;    }}

一些启发

  • 对于那些要求只能出现一次的情况,用set比较好,因为他会帮我们处理这些情况。
  • 对于一些算法,用array.sort()效果非常好,因为他是O(nlgn)的时间复杂度。

O(nlgn) : two points方法

public class Solution {    public int[] intersection(int[] nums1, int[] nums2) {        Set<Integer> set = new HashSet<>();        Arrays.sort(nums1);        Arrays.sort(nums2);        int i = 0;        int j = 0;        while (i < nums1.length && j < nums2.length) {            if (nums1[i] < nums2[j]) {                i++;            } else if (nums1[i] > nums2[j]) {                j++;            } else {                set.add(nums1[i]);                i++;                j++;            }        }        int[] result = new int[set.size()];        int k = 0;        for (Integer num : set) {            result[k++] = num;        }        return result;    }}

这里使用two points方法,算法时间复杂度为O(nlgn).空间复杂度为O(n)

最好的方法O(n):Hashset法

 public int[] intersection(int[] nums1, int[] nums2) {        Set<Integer> set = new HashSet<>();        Set<Integer> intersect = new HashSet<>();        for (int i = 0; i < nums1.length; i++) {            set.add(nums1[i]);        }        for (int i = 0; i < nums2.length; i++) {            if (set.contains(nums2[i])) {                intersect.add(nums2[i]);            }        }        int[] result = new int[intersect.size()];        int i = 0;        for (Integer num : intersect) {            result[i++] = num;        }        return result;    }

Intersaction of two arrays II

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.

hashmap解法

 public int[] intersect(int[] nums1, int[] nums2) {        int len1=nums1.length;        int len2=nums2.length;        if(len1==0||len2==0) return new int[0];        HashMap<Integer,Integer> map=new HashMap<Integer,Integer>();        for(int i = 0; i < nums1.length; i++)        {            if(map.containsKey(nums1[i])) map.put(nums1[i], map.get(nums1[i])+1);            else map.put(nums1[i], 1);        }        ArrayList<Integer> result=new ArrayList<>();        for(int i=0;i<len2;i++){            if(map.containsKey(nums2[i]) && map.get(nums2[i])>0){                result.add(nums2[i]);                map.put(nums2[i],map.get(nums2[i])-1);            }        }        int[] re=new int[result.size()];        int index=0;        for(int i=0;i<result.size();i++){            re[i]=result.get(i);        }        return re;    }

这里比较受启发的是它更新hashmap时用的是put(key, newValue)的方法
这个算法的时间复杂度是O(m+n)

two points解法

Arrays.sort(nums1);        Arrays.sort(nums2);        int pnt1 = 0;        int pnt2 = 0;        ArrayList<Integer> myList = new ArrayList<Integer>();        while((pnt1 < nums1.length) &&(pnt2< nums2.length)){            if(nums1[pnt1]<nums2[pnt2]){                pnt1++;            }            else{                if(nums1[pnt1]>nums2[pnt2]){                    pnt2++;                }                else{                    myList.add(nums1[pnt1]);                    pnt1++;                    pnt2++;                }            }        }        int[] res = new int[myList.size()];        for(int i = 0; i<res.length; i++){            res[i] = (Integer)myList.get(i);        }        return res;

这里可以学到,对于这种两个数组来比较大小的算法,two point方法总是很实用,并且two points方法总是伴随者先sort两个数组,再进行two point
这种算法的时间复杂度是O(m+n)

0 0