Given two arrays, write a function to compute their intersection.
Example:
Given nums1 = [1, 2, 2, 1]
, nums2 = [2, 2]
, return [2]
.
Note:
- Each element in the result must be unique.
- The result can be in any order.
题意:给定两个数组,判断它们的交集。
例:nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2].
note:
1. 返回的结果中每个元素都是唯一的,即不存在重复元素。
2. 返回的结果中的元素顺序任意。
思路1:使用两个set,一个set存放nums1中的元素,一个set存放交集。
遍历nums1,将nums1中的元素存入set中;
再遍历nums2,如果set中包含nums2[j],且result中还不包含nums2[j],则将nums2[j]存入result中。
遍历result中的元素,逐个存入数组array中,返回array
public int[] intersection(int[] nums1, int[] nums2) { Set<Integer> result = new HashSet<>(); Set<Integer> set = new HashSet<>(); for(int i = 0; i < nums1.length; i++){ //if(!set.contains(nums1[i]))//如果此 set 中尚未包含指定元素,则添加指定元素。如果此 set 已包含该元素,则该调用不更改 set 并返回 false。 set.add(nums1[i]);//因此在调用set.add(nums1[i])方法之前,不用先判断是否存在nums1[i](!set.contains(nums1[i]) } for(int j = 0; j < nums2.length; j++){ if(set.contains(nums2[j])){ //if(!result.contains(nums2[j])) result.add(nums2[j]); } } int[] array = new int[result.size()]; int i = 0; for(int num : result){//将Set类型的result中的元素逐个存入数组,即将set转为数组 array[i++] = num; } return array; }
注:开始以为set存入元素时,一定要先判断是否已经存在该元素,如果不存在才能插入。看LeetCode中的答案时,发现并没有先判断set中是否存在该元素,而是直接存入。
查看了set的api,发现set可以直接存入元素,而不必先判断该元素是否存在。
HashSet中add方法的说明:
如果此 set 中尚未包含指定元素,则添加指定元素。更确切地讲,如果此 set 没有包含满足 (e==null ? e2==null : e.equals(e2)) 的元素 e2,则向此 set 添加指定的元素 e。如果此 set 已包含该元素,则该调用不更改 set 并返回 false。
LeetCode中提供的另外两个方法:
思路2:先对nums1和nums2排序,用两个指针分别指向两个数组的起始元素,比较对应元素的大小。
如果nums1[i] < nums2[j],则说明nums1的元素小,将nums1的指针加1;反之nums2的指针加1;
如果nums1[i] = nums2[j],则说明该元素为交集,将nums1[i]存入set,同时让两个数组的指针都加1.
public int[] intersection(int[] nums1, int[] nums2){ Set<Integer> set = new HashSet<>(); Arrays.sort(nums1); Arrays.sort(nums2); int i = 0, j = 0; while(i < nums1.length && j < nums2.length){ if(nums1[i] < nums2[j]) i++; else if(nums1[i] > nums2[j]) j++; else{ //nums1[i] = nums2[j] set.add(nums1[i]); i++; j++; } } int k = 0; int[] nums = new int[set.size()]; for(int num : set){ nums[k++] = num; } return nums; }
思路3:用二分法查找
将一个数组排序,然后遍历另一个数组,把遍历到的每个数字在排序后的数组中用二分查找法搜索,如果能找到则放入结果set中
public int[] intersection(int[] nums1, int[] nums2){ Set<Integer> set = new HashSet<>(); Arrays.sort(nums1); for(int i = 0; i < nums2.length; i++){ if(binarySearch(nums1,nums2[i])) set.add(nums2[i]); } int i = 0; int[] nums= new int[set.size()]; for(int num : set){ nums[i++] = num; } return nums; } public boolean binarySearch(int[] nums, int target){ int left = 0, right = nums.length - 1; while(left <= right){ int mid = left + (right - left) / 2; if(nums[mid] == target) return true; if(nums[mid] < target) left = mid + 1; else right = mid - 1; } return false; }