LeetCode-350. 两个数组的交集 II

题目

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

示例 1:

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

示例 2:

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

说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。
进阶:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

解题

  • 这个其实和349号问题差不多, 唯一的区别就是, 这个允许重复元素, 所以这里就不能使用Set来解决, 但是可以使用Map来解决, 记录每个元素从出现的个数即可, 取交集的时候, 按元素个数小的来取, 代码如下:
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        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[] result = new int[set2.size()];
        int i = 0;
        for (Integer integer : set2) {
            result[i] = integer;
            i++;
        }

        return result;
    }
}

下面也贴一下LeetCode提交记录中耗时最短的解:

class Solution {
  	public int[] intersection2(int[] nums1, int[] nums2) {
		Set<Integer> set = new HashSet<>();
		Set<Integer> result = 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])) {
				result.add(nums2[i]);
			}
		}
		int[] res = new int[result.size()];
		int i = 0;
		Iterator<Integer> iter = result.iterator();
		while (iter.hasNext()) {
			res[i++] = (int) iter.next(); // 集合变数组
		}
		return res;
	}
    /**
	 * 标记法
	 * 
	 * @param nums1
	 * @param nums2
	 * @return
	 */
	public int[] intersection(int[] nums1, int[] nums2) {
		int max = Integer.MIN_VALUE;
		int min = Integer.MAX_VALUE;
		// 求出数组nums1中最大值 与最小值
		for (int i = 0; i < nums1.length; i++) {
			max = max < nums1[i] ? nums1[i] : max;
			min = min > nums1[i] ? nums1[i] : min;
		}
		// 标记
		boolean[] booleanArray = new boolean[max - min + 1];
		for (int i = 0; i < nums1.length; i++) {
			booleanArray[nums1[i] - min] = true;
		}
		int index = 0;
		int[] tempArray = new int[nums2.length];
		for (int i = 0; i < nums2.length; i++) {
			// 找出nums2中的元素,标记改为false
			if (!(nums2[i] < min) && !(nums2[i] > max) && booleanArray[nums2[i] - min]) {
				booleanArray[nums2[i] - min] = false;
				// 找出相同的数据
				tempArray[index++] = nums2[i];
			}
		}
		// 复制
		return Arrays.copyOf(tempArray, index);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值