LeetCode_349. 两个数组的交集
【摘要】
文章目录
题目分析Code方式一 :Set + 数组方式二: 两个 set方式三: 内置函数
题目
https://leetcode-cn.com/problems/inter...
题目
https://leetcode-cn.com/problems/intersection-of-two-arrays/
分析
幼稚的方法是根据第一个数组 nums1 迭代并检查每个值是否存在在 nums2 内。如果存在将值添加到输出。这样的方法会导O(n×m)
的时间复杂性,其中 n 和 m 是数组的长度。
为了在线性时间内解决这个问题,我们使用集合 set,在 O(1)
时间复杂度实现操作。
其思想是将两个数组转换为集合 set,然后迭代较小的集合检查是否存在在较大集合中。平均情况下,这种方法的时间复杂度为 O(n+m)
Code
方式一 :Set + 数组
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
/**
*
*
* @ClassName: Solution
*
* @Description: 给定两个数组,编写一个函数来计算它们的交集。
*
* 输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序。
* @author: Mr.Yang
*
* @date: 2020年2月9日 下午3:39:28
*/
public class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
// 保存目标元素的集合
List<Integer> targetList = new ArrayList<>();
// set 元素不重复 ,存放数组1
Set<Integer> set = new TreeSet<>();
for (int num : nums1) {
set.add(num);
}
// 遍历数组2,判断是数组2中的每个元素是否在数组1中
// 存在则加入到targetList
// 同时为了防止数组2有重复的数据,导致targetList重复,所以要移除set中的元素,防止重复
for (int num2 : nums2) {
if (set.contains(num2)) {
targetList.add(num2);
set.remove(num2);
}
}
// list转数组
int[] target = new int[targetList.size()];
for (int i = 0; i < target.length; i++) {
target[i] = targetList.get(i);
}
return target;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] target = solution.intersection(new int[] { 1, 2, 2, 1 }, new int[] { 2, 2 });
for (int i = 0; i < target.length; i++) {
System.out.println(target[i] + ",");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
方式二: 两个 set
public int[] intersection3(int[] nums1, int[] nums2) {
// 数组1 入set
HashSet<Integer> set1 = new HashSet<Integer>();
for (Integer n : nums1) {
set1.add(n);
}
// 数组2 入set
HashSet<Integer> set2 = new HashSet<Integer>();
for (Integer n : nums2) {
set2.add(n);
}
// 比较
if (set1.size() < set2.size()) {
return setIntersection(set1, set2);
} else {
return setIntersection(set2, set1);
}
}
/**
*
*
* @Title: setIntersection
*
* @Description: 迭代较小的集合检查是否存在在较大集合中 减少遍历次数
*
* @param smallSet
* @param largeSet
*
* @return: int[]
*/
private int[] setIntersection(HashSet<Integer> smallSet, HashSet<Integer> largeSet) {
int[] target = new int[smallSet.size()]; // 先开辟一个小的内存区域
int idx = 0;// 下面的这种遍历,没有下标,定义一个索引下标
for (int num : smallSet) {// 迭代较小的集合检查是否存在在较大集合中 减少遍历次数
if (largeSet.contains(num)) {
// target[idx] = num;
// idx++;
// 上面两行可以直接写成如下
target[idx++] = num;
}
}
return Arrays.copyOf(target, idx); // 返回idx长度的数组,避免出现多余的0
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
复杂度分析
- 时间复杂度:
O(m+n)
,其中 n 和 m 是数组的长度。O(n)
的时间用于转换 nums1 在集合中,O(m)
的时间用于转换 nums2 到集合中,并且平均情况下,集合的操作为O(1)
- 空间复杂度:
O(m+n)
,最坏的情况是数组中的所有元素都不同。
方式三: 内置函数
内置的函数在一般情况下的时间复杂度是 O(n+m)
且时间复杂度最坏的情况是 O(n×m)
,在 Java 提供了 retainAll()
函数.
public int[] intersection(int[] nums1, int[] nums2) {
// 数组1 入set
HashSet<Integer> set1 = new HashSet<Integer>();
for (Integer n : nums1)
set1.add(n);
// 数组2 入set
HashSet<Integer> set2 = new HashSet<Integer>();
for (Integer n : nums2)
set2.add(n);
// 内置函数
set1.retainAll(set2);
// set转数组
int[] output = new int[set1.size()];
int idx = 0;
for (int s : set1)
output[idx++] = s;
return output;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
复杂度分析
- 时间复杂度:一般情况下是
O(m+n)
,最坏情况下是O(m×n)
。 - 空间复杂度:最坏的情况是
O(m+n)
,当数组中的元素全部不一样时。
文章来源: artisan.blog.csdn.net,作者:小小工匠,版权归原作者所有,如需转载,请联系作者。
原文链接:artisan.blog.csdn.net/article/details/104235575
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)