求兩個有序整數集合的交集,比比誰的算法快!


阿里巴巴一道筆試題題目:有兩個有序整數集合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 毫秒

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM