zoukankan      html  css  js  c++  java
  • 两个数组的交集【349】

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

    示例 1:

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

    示例 2:

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

    一.双集合

    思路:

    将两个数组分别放入两个set集合中,比较一个集合是否包含另一个集合的字段,如果包含就放入集合中
    
    class Solution {
        public int[] intersection(int[] nums1, int[] nums2) {
    
            List<Integer> list = new ArrayList();
    
            Set<Integer> num1Set = new HashSet();
            Set<Integer> num2Set = new HashSet();
    
            for(int i = 0; i < nums1.length; i++){
                num1Set.add(nums1[i]);
            }
    
            for(int i = 0; i < nums2.length; i++){
                num2Set.add(nums2[i]);
            }
             for(int key: num1Set){
                if(num2Set.contains(key)){
                    list.add(key);
                }
            }
    
            int num3[] = list.stream().mapToInt(Integer::valueOf).toArray();
    
            return  num3;
            
        }
    }
    
    //大佬的写法:
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> set = Arrays.stream(nums1).boxed().collect(Collectors.toSet());
        return Arrays.stream(nums2).distinct().filter(set::contains).toArray();
    }
    

    复杂度分析

    • 时间复杂度:O(m+n),其中 m 和 n 分别是两个数组的长度。使用两个集合分别存储两个数组中的元素需要 O(m+n) 的时间,遍历较小的集合并判断元素是否在另一个集合中需要O(min(m,n)) 的时间,因此总时间复杂度是 O(m+n)。
    • 空间复杂度:O(m+n),其中 m 和 n 分别是两个数组的长度。空间复杂度主要取决于两个集合。

    二.排序 + 双指针

    思路:

    首先对两个数组进行排序,然后使用两个指针遍历两个数组。可以预见的是加入答案的数组的元素一定是递增的,为了保证加入元素的唯一性,我们需要额外记录变量 pre表示上一次加入答案数组的元素。
    初始时,两个指针分别指向两个数组的头部。每次比较两个指针指向的两个数组中的数字,如果两个数字不相等,则将指向较小数字的指针右移一位,如果两个数字相等,且该数字不等于 pre ,
    将该数字添加到答案并更新 pre 变量,同时将两个指针都右移一位。当至少有一个指针超出数组范围时,遍历结束。
    

    代码:

    class Solution {
        public int[] intersection(int[] nums1, int[] nums2) {
            Arrays.sort(nums1);
            Arrays.sort(nums2);
            int length1 = nums1.length, length2 = nums2.length;
            int[] intersection = new int[length1 + length2];
            int index = 0, index1 = 0, index2 = 0;
            while (index1 < length1 && index2 < length2) {
                int num1 = nums1[index1], num2 = nums2[index2];
                if (num1 == num2) {
                    // 保证加入元素的唯一性
                    if (index == 0 || num1 != intersection[index - 1]) {
                        intersection[index++] = num1;
                    }
                    index1++;
                    index2++;
                } else if (num1 < num2) {
                    index1++;
                } else {
                    index2++;
                }
            }
            return Arrays.copyOfRange(intersection, 0, index);
        }
    }
    

    复杂度分析

    • 时间复杂度:O(mlogm+nlogn),其中 m 和 n 分别是两个数组的长度。对两个数组排序的时间复杂度分别是 O(mlogm) 和 O(nlogn),双指针寻找交集元素的时间复杂度是 O(m+n),因此总时间复杂度是 O(mlogm+nlogn)。

    • 空间复杂度:O(logm+logn),其中 m 和 n 分别是两个数组的长度。空间复杂度主要取决于排序使用的额外空间。

  • 相关阅读:
    Undefined symbols for architecture armv7错误解决方法
    一个iOS 框架介绍:MKNetworkKit
    objective-c之各种数值
    利用openURL,在IOS应用中打开另外一个应用
    hackerrank---List Comprehensions
    LeetCode --- Plus One
    Vim学习与总结
    LeetCode --- Pascal's Triangle II
    LeetCode --- Gray Code
    LeetCode --- Two Sum
  • 原文地址:https://www.cnblogs.com/snail-gao/p/13915572.html
Copyright © 2011-2022 走看看