劍指offer50 陣列中重複的數字(java)
阿新 • • 發佈:2018-11-25
題目
在一個長度為n的數組裡的所有數字都在0到n-1的範圍內。 陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意一個重複的數字。 例如,如果輸入長度為7的陣列{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字2。
思路1
把當前序列當成是一個下標和下標對應值是相同的陣列,遍歷陣列,判斷當前位的值和下標是否相等
- 若相等,則遍歷下一位;
- 若不等,則將當前位置i上的元素和a[i]位置上的元素比較:
- 若它們相等,則找到了第一個相同的元素;
- 若不等,則將它們兩交換。換完之後a[i]位置上的值和它的下標是對應的,但i位置上的元素和下標並不一定對應;重複2的操作,直到當前位置i的值也為i,遍歷下一位。
程式碼1
/** * 重複的數字交給a[0] */ public static boolean duplicate(int[] a, int length) { if (length == 0) return false; for (int i = 0; i < length; i++) if (a[i] > length) return false; for (int i = 0; i < length; i++) { while (i != a[i]) { if (a[i] == a[a[i]]) { a[0] = a[i]; return true; } int tem = a[i]; a[i] = a[tem]; a[tem] = tem; } } return false; }
思路2(很巧妙,思路源於作者)
題目裡寫了數組裡數字的範圍保證在0 ~ n-1 之間,所以可以利用現有陣列設定標誌,當一個數字被訪問過後,可以設定對應位上的數 + n,之後再遇到相同的數時,會發現對應位上的數已經大於等於n了,那麼直接返回這個數即可
程式碼2
/** * 重複的數字交給a[0] */ public static boolean duplicate2(int[] a, int length) { if (length == 0) return false; for (int i = 0; i < length; i++) if (a[i] > length) return false; for (int i = 0; i < length; i++) { int index = a[i]; if (index >= length) index -= length; if (a[index] >= length) { a[0] = index; return true; } a[index] += length; } return false; }