1. 程式人生 > >有一個100萬的陣列,裡邊有兩個是重複的,如何設計演算法找到

有一個100萬的陣列,裡邊有兩個是重複的,如何設計演算法找到

輸出:兩個重複的元素的索引

首先,直接兩重迴圈查詢不是不行,估計是最蠢的做法了。

其次,先用快速排序拍一遍,然後遍歷,時間複雜度最好的情況是最壞的情況是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的實現過程,下了如下程式碼:

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 + "]";
		}
	}
由於這裡的元素都是int 型別的,在進行資料雜湊的時候,這裡為了圖方便,沒有取hashCode,如果是String或者其他型別可以使用HashCode進行雜湊。

如果HashCode雜湊的比較好,最好的情況下,不需要進行連結串列操作,那麼整個演算法的時間複雜度就是O(n),最壞的情況下是HashCode完全沒有雜湊開,時間複雜度為O(n^2)

當然這裡使用HashMap方式來實現也是可以的,value作為key,index作為value,通過containsKey方法判斷當前是否已存在該key,如果已存在直接取出來就達到目的了。

如果非要自己找點事情做的話,還是通過Hash的思路來:

假設每一個元素陣列中都是散裂開的,沒有重複的,那麼這時候的時間複雜度豈不是最高?問題在於如何保證HashCode絕對不重複。

未完待續……