分析
兩個陣列的交集,雙指標使用的前提是,兩個陣列已經處於有序狀態。雙指標的本質是遍歷;雙指標線上性資料結構中,進行資料處理,每次只專注於兩個元素;指標遍歷將問題拆解為兩部分,即已解決和待解決問題。倘若兩個陣列是無序的狀態,雙指標指向每次都無法確認是否在歷史中已經出現過,這個時候其實就是雙層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);
}
}