这道题最简单的思路是用三个set,把三个数组的数放在set中,然后检查set1中的每个数是不是在set2和set3中,但是这样做的缺点是,set不是sorted的,最后要对结果排序,时间复杂度最坏情况是O(nlogn) (n是三个数组中的最小长度).
public List<Integer> arraysIntersection(int[] arr1, int[] arr2, int[] arr3) { List<Integer> res = new ArrayList<>(); Set<Integer> set1 = new HashSet<>(); Set<Integer> set2 = new HashSet<>(); Set<Integer> set3 = new HashSet<>(); for(int i=0;i<arr1.length;i++){ set1.add(arr1[i]); } for(int i=0;i<arr2.length;i++){ set2.add(arr2[i]); } for(int i=0;i<arr3.length;i++){ set3.add(arr3[i]); } for(int n: set1){ if(set2.contains(n)&&set3.contains(n)) res.add(n); } Collections.sort(res); return res; }
Binary Search 算法,在arr2 和arr3中查找是否有arr1中的每个数,时间复杂度:O(m*log(x)+log(y)), m是数组1的长度,x,y分别是数组2和3的长度。
public List<Integer> arraysIntersection(int[] arr1, int[] arr2, int[] arr3) { List<Integer> res = new ArrayList<>(); for(int i=0;i<arr1.length;i++){ if(binarySearch(arr2, arr1[i])&&binarySearch(arr3, arr1[i])) res.add(arr1[i]); } return res; } private boolean binarySearch(int[] arr, int target){ int l = 0, r = arr.length-1; while(l<=r){ int mid = (l+r)/2; if(arr[mid]==target) return true; else if(arr[mid]<target){ l= mid+1; } else r = mid-1; } return false; }
最后抄一个one pass的算法,时间复杂度O(n),n是3个数组中的最小长度。
public List<Integer> arraysIntersection(int[] arr1, int[] arr2, int[] arr3) { List<Integer> res = new ArrayList<>(); int i1=0, i2=0, i3=0; while(i1<arr1.length && i2<arr2.length && i3<arr3.length){ if(arr1[i1]==arr2[i2]&&arr2[i2]==arr3[i3]){ res.add(arr1[i1]); i1++;i2++;i3++; } else if(arr1[i1]<arr2[i2]) i1++; else if(arr2[i2]<arr3[i3]) i2++; else i3++; } return res; }