力扣-两个数组的交集

题目描述

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

示例 1:

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

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

说明:
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/intersection-of-two-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目分析

1:要求输出结果的每个元素唯一 ——> 去重操作,为方便去重操作,可以使用 哈希表-HashSet存储结果集

哈希表的使用:可以用数组来存储,但我们不明确结果的长度,所以不能采用数组。
Java中Hash的两种数据结构:
HashSet 集合 非重复
HashMap集合 存<key,value>
所以,采用HashSet作为结果的存储类型

解法1:-最直观(暴力法)的方法:

1:两层for 循环,对nums1数组中的每一个元素,判断是否在nums2中,若存在将结果存入HashSet集合中(避免手动去重);
2:返回:将HashSet 转化为 int[]数组进行返回;

代码:

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        HashSet<Integer> result = new HashSet<Integer>();
        
        for(int i = 0; i< nums1.length; i++){
            for(int j = 0;j < nums2.length; j++){
                if(nums1[i] == nums2[j]){
                    result.add(nums2[j]);
                }
            }
        }
        //HashSet的result转换成int[] 
        
        //方法1
       // int[] hashSetToInt = new int[result.size()];
        //int index = 0;
        //for(int num : result){
           // hashSetToInt[index++] = num;
        //}
        //return hashSetToInt;
        
        //不用遍历,直接将HashSet转换为Int[]方法
        return result.stream().mapToInt(t -> t).toArray();
    }
}

解法2 --借助哈希表优化查找时间复杂度

为优化时间复杂度,在查找nums1中元素是否在nums2中时,除了循环遍历,可以通过哈希表来判断元素是否在一个集合中,时间复杂度为O(1)
1: 将nums1数组映射到哈希表上
2:判断nums2中的元素是否在num1数组对应的哈希表中

代码:

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        HashSet<Integer> set1 = new HashSet<Integer>();

        HashSet<Integer> result = new HashSet<Integer>();
        
        for(int i : nums1){
            set1.add(i);
        }

        for(int j : nums2){
            if(set1.contains(j)){
                result.add(j);
            }
        }

        //HashSet的result转换成int[]

	 //方法1
       // int[] hashSetToInt = new int[result.size()];
        //int index = 0;
        //for(int num : result){
           // hashSetToInt[index++] = num;
        //}
        //return hashSetToInt;
        
        //不用遍历,直接将HashSet转换为Int[]方法
        return result.stream().mapToInt(t -> t).toArray();
    }
}

解法3:排序 + 双指针

若两数组有序,可以通过双指针来求出两数组的交集。为了保证结果数组(肯定有序)中元素的唯一,新增加的元素与结果集合中最后一个元素比较
步骤:
对两个数组进行排序;
定义两个指针,初始化为排序后的数组的起始位置;
判断两指针对应元素是否相等并且不是结果集中最后一个元素,若相等且不在结果集合中,则存入结果集;
否则,将较小元素的指针向后移动。

代码

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        //排序+双指针
        Arrays.sort(nums1);
        Arrays.sort(nums2);

        int length1= nums1.length;
        int length2 = nums2.length;

        int[] result = new int[length1+length2];

        int i = 0,j = 0;
        int index=0;
        while(i < length1 && j < length2){

            if(nums1[i] == nums2[j]){
                if(index == 0 || nums1[i] != result[index-1]){
                    result[index++] = nums1[i];
                }
                i++;j++;
            }else if(nums1[i] < nums2[j]){
                i++;
            }else{
                j++;
            }
        }

        // int[]数组初始化时,将所有元素值初始化为0,
        //返回结果,处理下
        //输出:[2,0,0,0,0,0]
        

        return Arrays.copyOfRange(result,0,index);
    }
}

注意:

注意:在题目中,我们不明确结果集中的数据内容,采用动态初始化方式定义数组result,长度取可能的最大值(两个数组长度之和),结果数组中的元素自动拥有一个默认值:0,该结果数组不能直接返回,需要进行处理
Arrays.copyOfRange(T[] orginal,int from,int end)将原始数组orginal,从下标from开始复制,直到上标end,生成并返回一个新的数组;[from,end)

【基础拓展整理1】
数组的初始化的三种方法(指定长度+指定内容+省略模式)
1:动态初始化(指定长度)
格式:数据类型[] 数组名称 = new 数据类型[数组长度];
元素为自动拥有一个默认值;
2: 静态初始化 (指定内容)
格式:数据类型[] 数组名称 = new 数据类型[] {元素1,元素2,…}

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页