大家好,我是听雨,是一名跨考计算机专业的研一学生。为提高编程的水平,计划每天刷编程题目。由于我是算法小白,所以开始只能从简单题开始写贴,请大家多多包涵,希望和大家一起进步
题目
今天的第一题为 力扣350. 两个数组的交集
解题思路
该题看上去难度不大,目的在于如何找两个数组的交集,暴力枚举是可以得到结果的,但是时间复杂度为 O ( n 2 ) O(n^2) O(n2),相对较长。本文采用了两种方法来进行优化。
一 . 双指针
对于乱序的数组来说,我们寻找其重复值比较麻烦,因为没有规律,无疑大海捞针。因此可以先对数组本身进行处理,将这两个数组先排序,然后再比较。排序的时间复杂度为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。得到排好序的两个数组之后,便可以设置两个指针来分别指向两个数组。由于数组是有序的,假设两个指针指向的值为a 和 b,两个数比较无疑有三种结果:
1.
a
>
b
a > b
a>b ,则指向b的指针向后右移动继续比较
2.
a
<
b
a < b
a<b ,则指向a的指针向后右移动继续比较
3.
a
=
b
a = b
a=b ,说明该元素为重复元素,存入结果数组
代码如下:
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
//先排序
Arrays.sort(nums1);
Arrays.sort(nums2);
int i = 0, j = 0;
int len1 = nums1.length;
int len2 = nums2.length;
//存放结果数组
int[] res = new int[len1];
int res_index = 0;
while( i < len1 && j < len2){
if(nums1[i] < nums2[j] ){
i++;
}else if(nums1[i] > nums2[j]){
j++;
}else{
res[res_index] = nums1[i];
i++;
j++;
res_index++;
}
}
return Arrays.copyOfRange(res, 0,res_index);
}
}
这样跑出来的结果为:
二. 哈希表
其实这道题的题目和【Day 2】LeetCode 1.两数之和 有点类似,也是可以通过哈希表的方法来处理。这里先将 nums1 数组的元素全部放入哈希表中,这个哈希表的键值对为【数组元素 — 元素的个数】。做到这点,只需要先看哈希表中是否有该 key 如果不存在,便将其加入,值设为1,如果已经存在,其值加1即可。得到哈希表之后,便只要遍历nums2 数组即可,如果存在该key,则将其值减一并存放到结果数组当中,直到该 key 的值为 0 就跳过。由于只需要遍历两个数组一次,所以算法的时间复杂度为 O ( n ) O(n) O(n)。
代码如下:
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
HashMap<Integer,Integer> map = new HashMap();
int[] res = new int[nums1.length];
int res_index = 0;
int count;
for(int i = 0; i < nums1.length; i++){
//如果已经放入哈希表,则其次数加一
if(map.containsKey(nums1[i])){
count = map.get(nums1[i]);
count ++;
map.put(nums1[i],count);
}else{
map.put(nums1[i] , 1);
}
}
for(int j = 0 ; j < nums2.length; j++){
if(map.containsKey(nums2[j]) && map.get(nums2[j]) > 0) {
res[res_index++] = nums2[j];
map.put(nums2[j], map.get(nums2[j]) - 1);
}
}
return Arrays.copyOfRange(res, 0,res_index);
}
}
这是结果,感觉都差不多。
总结
这道题的两种方法还是比较容易想到的,不得不说哈希表是个好东西。对了!大家对于文章的内容和风格有什么建议请评论给我,不胜感激!