阿里巴巴一道筆試題題目:有兩個有序整數集合a和b,寫一個函數找出它們的交集?
方法一:
1 private static Set<Integer> setMethod(int[] a,int[] b){ 2 Set<Integer> set = new HashSet<Integer>(); 3 Set<Integer> set2 = new HashSet<Integer>(); 4 for(int i=0; i<a.length; i++) { 5 set.add(a[i]); 6 } 7 for(int j=0; j<b.length; j++) { 8 if(!set.add(b[j])) 9 set2.add(b[j]); 10 } 11 return set2; 12 }
方法二:
1 private static Set<Integer> forMethod(int[] a,int[] b){ 2 Set<Integer> set=new HashSet<Integer>(); 3 int i=0,j=0; 4 while(i<a.length && j<b.length){ 5 if(a[i]<b[j]) 6 i++; 7 else if(a[i]>b[j]) 8 j++; 9 else{ 10 set.add(a[i]); 11 i++; 12 j++; 13 } 14 } 15 return set; 16 }
方法三:
1 private static int[] intersect(int[] a, int[] b) { 2 if (a[0] > b[b.length - 1] || b[0] > a[a.length - 1]) { 3 return new int[0]; 4 } 5 int[] intersection = new int[Math.max(a.length, b.length)]; 6 int offset = 0; 7 for (int i = 0, s = i; i < a.length && s < b.length; i++) { 8 while (a[i] > b[s]) { 9 s++; 10 } 11 if (a[i] == b[s]) { 12 intersection[offset++] = b[s++]; 13 } 14 while (i < (a.length - 1) && a[i] == a[i + 1]) { 15 i++; 16 } 17 } 18 if (intersection.length == offset) { 19 return intersection; 20 } 21 int[] duplicate = new int[offset]; 22 System.arraycopy(intersection, 0, duplicate, 0, offset); 23 return duplicate; 24 }
三種方法的性能對比測試:
1 public class NumberCrossTest { 2 public static void main(String[] args) { 3 int[] a1 = new int[100000]; 4 for (int i = 0; i < a1.length; i++) { 5 a1[i] = i + 10; 6 } 7 int[] a2 = new int[200000]; 8 for (int i = 0; i < a2.length; i++) { 9 a2[i] = i + 20; 10 } 11 long begin = System.currentTimeMillis(); 12 Set<Integer> set1 = setMethod(a1, a2); 13 long end = System.currentTimeMillis(); 14 System.out.println(end - begin);// 359
15 begin = System.currentTimeMillis(); 16 Set<Integer> set2 = forMethod(a1, a2); 17 end = System.currentTimeMillis(); 18 System.out.println(end - begin);// 160
19 begin = System.currentTimeMillis(); 20 int[] c = intersect(a1, a2); 21 end = System.currentTimeMillis(); 22 System.out.println(end - begin);// 10 23 // 測試兩種方法的結果是否相等
24 System.out.println(set1.equals(set2));// true
25 Set<Integer> set3 = new HashSet<Integer>(); 26 for (int i = 0; i < c.length; i++) { 27 set3.add(c[i]); 28 } 29 System.out.println(set1.equals(set3));// true
30 } 31
32 private static Set<Integer> setMethod(int[] a, int[] b) { 33 Set<Integer> set = new HashSet<Integer>(); 34 Set<Integer> set2 = new HashSet<Integer>(); 35 for (int i = 0; i < a.length; i++) { 36 set.add(a[i]); 37 } 38 for (int j = 0; j < b.length; j++) { 39 if (!set.add(b[j])) 40 set2.add(b[j]); 41 } 42 return set2; 43 } 44
45 private static Set<Integer> forMethod(int[] a, int[] b) { 46 Set<Integer> set = new HashSet<Integer>(); 47 int i = 0, j = 0; 48 while (i < a.length && j < b.length) { 49 if (a[i] < b[j]) 50 i++; 51 else if (a[i] > b[j]) 52 j++; 53 else { 54 set.add(a[i]); 55 i++; 56 j++; 57 } 58 } 59 return set; 60 } 61
62 private static int[] intersect(int[] a, int[] b) { 63 if (a[0] > b[b.length - 1] || b[0] > a[a.length - 1]) { 64 return new int[0]; 65 } 66 int[] intersection = new int[Math.max(a.length, b.length)]; 67 int offset = 0; 68 for (int i = 0, s = i; i < a.length && s < b.length; i++) { 69 while (a[i] > b[s]) { 70 s++; 71 } 72 if (a[i] == b[s]) { 73 intersection[offset++] = b[s++]; 74 } 75 while (i < (a.length - 1) && a[i] == a[i + 1]) { 76 i++; 77 } 78 } 79 if (intersection.length == offset) { 80 return intersection; 81 } 82 int[] duplicate = new int[offset]; 83 System.arraycopy(intersection, 0, duplicate, 0, offset); 84 return duplicate; 85 } 86 }
結果對比:
方法一用時:359 毫秒
方法二用時:160 毫秒
方法三用時:10 毫秒