有一個100萬的陣列,裡邊有兩個是重複的,如何設計演算法找到
阿新 • • 發佈:2019-02-10
輸出:兩個重複的元素的索引
首先,直接兩重迴圈查詢不是不行,估計是最蠢的做法了。
其次,先用快速排序拍一遍,然後遍歷,時間複雜度最好的情況是最壞的情況是nlogn+n
有人說是用hash,有人說用點陣圖,不知道什麼情況,用起來估計很麻煩。
其實最好想的一個方式為HashSet方式,在數量不那麼大的情況下沒問題的,100萬同時載入到記憶體中可以接受,主要考慮時間複雜度。
程式碼如下:
int a[] = { 6, 4, 18, 10, 24, 8, 9, 16, 19, 13, 25, 15, 12, 11, 2, 0, 14, 17, 12, 5 }; int n = a.length; Set<Integer> intSet = new HashSet<Integer>(); for (int i = 0; i < n; i++) { if (!intSet.add(a[i])) { System.out.println(a[i]); break; } }
這裡只把第二重複的元素打印出來了,如果還需要找前一個,就需要更多的操作了,比如HashSet中儲存一個物件,同時包含index/value,找到重複的value之後,通過遍歷比較value獲取index。這裡需要多加一個遍歷的過程。
模擬HashMap的實現過程,下了如下程式碼:
由於這裡的元素都是int 型別的,在進行資料雜湊的時候,這裡為了圖方便,沒有取hashCode,如果是String或者其他型別可以使用HashCode進行雜湊。public void testFindRepeatInt2() { int a[] = { 6, 4, 18, 10, 24, 8, 9, 16, 19, 13, 25, 15, 12, 11, 2, 0, 14, 17, 12, 5 }; int n = a.length; IndexValue iv[] = new IndexValue[n]; IndexValue target = null; for (int i = 0; i < n; i++) { if (null != (target = put(a, i, iv))) { System.out.println("第一個數:a【" + target.index + "】==" + target.value); System.out.println("第二個數:a【" + i + "】==" + a[i]); break; } } System.out.println(Arrays.toString(iv)); } private IndexValue put(int[] a, int i, IndexValue[] iv) { int index = a[i] % iv.length; IndexValue target = null; if (iv[index] == null) { iv[index] = new IndexValue(i, a[i]); } else { IndexValue temp = iv[index]; if (null != (target = contains(temp, a[i]))) { return target; } else { IndexValue newIv = new IndexValue(i, a[i]); newIv.next = temp; iv[index] = newIv; } } return target; } private IndexValue contains(IndexValue temp, int value) { if (temp.value == value) { return temp; } if (temp.next != null) { return contains(temp.next, value); } return null; } class IndexValue { int index; int value; IndexValue next; public IndexValue(int index, int value) { super(); this.index = index; this.value = value; } @Override public String toString() { return "IndexValue [index=" + index + ", value=" + value + ", next=" + next + "]"; } }
如果HashCode雜湊的比較好,最好的情況下,不需要進行連結串列操作,那麼整個演算法的時間複雜度就是O(n),最壞的情況下是HashCode完全沒有雜湊開,時間複雜度為O(n^2)
當然這裡使用HashMap方式來實現也是可以的,value作為key,index作為value,通過containsKey方法判斷當前是否已存在該key,如果已存在直接取出來就達到目的了。
如果非要自己找點事情做的話,還是通過Hash的思路來:
假設每一個元素陣列中都是散裂開的,沒有重複的,那麼這時候的時間複雜度豈不是最高?問題在於如何保證HashCode絕對不重複。
未完待續……