LeetCode | 349 Intersection Of Two Arrays
分析
两个数组的交集,双指针使用的前提是,两个数组已经处于有序状态。双指针的本质是遍历;双指针在线性数据结构中,进行数据处理,每次只专注于两个元素;指针遍历将问题拆解为两部分,即已解决和待解决问题。倘若两个数组是无序的状态,双指针指向每次都无法确认是否在历史中已经出现过,这个时候其实就是双层for循环。
- 排序
- 双指针移动,任意一个移动到末尾需要直接停止
- 去重判断
- 移除结果数组末端的0
HashSet,哈希在寻找唯一性上有独特的优势,再加上Set的性质,相对于双指针方式,就像是在作弊一样。天然存在了去重和唯一性。
- 将其中一个数组放进HashSet中,即完成了去重操作
- 另一个数组中逐个遍历找到重叠的部分
- 用ArrayList存储于HashSet中重叠的部分数据
主类
package com.github.dolphinmind.hash;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
/**
* @author dolphinmind
* @ClassName intersectionoftwoarrays
* @description 349 求两个数组的交集
* @date 2024/8/9
*/
public class InterSectionOfTwoArrays {
/**
* 双指针写法
* @param nums1
* @param nums2
*/
public void intersectionTwoPointers(int[] nums1, int[] nums2) {
if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
System.out.println("数组为空");
return;
}
Arrays.sort(nums1);
Arrays.sort(nums2);
int len = Math.min(nums1.length, nums2.length);
int[] res = new int[len];
int i = 0, j = 0, index = 0;
while (i < nums1.length && j < nums2.length) {
if (nums1[i] < nums2[j]) {
i++;
} else if (nums1[i] > nums2[j]) {
j++;
} else {
/**
* 避免重复
* 首次添加元素:如果index == 0,说明结果数组还没有任何元素,此时直接将找到的交集元素添加到结果数组中
* 避免重复添加:如果index != 0, 说明结果数组中已经有至少一个元素。此时需要检查当前要添加的元素是否与结果数组中的最后一个元素相同
* 如果相同,则跳过本次循环,继续下一次循环,直到找到不同的元素
*/
if (index == 0 || res[index - 1] != nums1[i]) {
res[index++] = nums1[i];
}
i++;
j++;
}
}
printArray(removeZeros(res, index));
}
/**
* 去除数组中0
* @param arr
* @param index
* @return
*/
public int[] removeZeros(int[] arr, int index) {
int[] newArr = new int[index];
for (int i = 0; i < index; i++) {
newArr[i] = arr[i];
}
return newArr;
}
public void printArray(int[] arr) {
System.out.print("[");
for (int item : arr) {
System.out.print(item + " ");
}
System.out.println("]");
System.out.println();
}
/**
* HashSet写法
*/
public void interSectionHashSet(int[] arr1, int[] arr2) {
HashSet<Integer> set = new HashSet<>();
List<Integer> res = new ArrayList<>();
for (int item : arr1) {
set.add(item);
}
for (int item : arr2) {
if (set.contains(item)) {
res.add(item);
}
}
/**
* 将List转换为数组.尽管mapToInt并没有改变流中的元素,但是它的作用是将Stream转换为IntStream
* 以便最后能够直接使用.toArray()方法得到一个int[]类型
*/
printArray(res.stream().mapToInt(x -> x).toArray());
}
}
测试类
package com.github.dolphinmind.hashcode;
import com.github.dolphinmind.hash.InterSectionOfTwoArrays;
import org.junit.Test;
/**
* @author dolphinmind
* @ClassName InterSectionOfTwoArraysTest
* @description
* @date 2024/8/9
*/
public class InterSectionOfTwoArraysTest {
@Test
public void test_intersection() {
int[] nums1 = {};
int[] nums2 = {3,4,5,6,7,8};
new InterSectionOfTwoArrays().intersectionTwoPointers(nums1, nums2);
}
@Test
public void test_interSectionHashSet() {
int[] nums1 = {1,2,3,4,5,6,7,8};
int[] nums2 = {3,4,5,6,7,8};
new InterSectionOfTwoArrays().interSectionHashSet(nums1, nums2);
}
}