在一個長度爲 n 的數組裏,全部數字都在 0 到 n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複,也不知道每一個數字重複幾回。請找出數組中第一個重複的數字。例如,若是輸入長度爲 7 的數組 {2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字 2java
利用 HashMap 鍵不重複的特性,能夠輕鬆找出第一個重複的數字數組
/* * 返回描述: * 若是數組中有重複的數字,函數返回true,不然返回false * 若是數組中有重複的數字,把重複的數字放到參數duplication[0]中 */ import java.util.HashMap; public class Solution { public boolean duplicate(int numbers[],int length,int [] duplication) { boolean flag = false; HashMap<Integer, Object> map = new HashMap<>(); for(int i = 0; i < length; i++) { if(map.containsKey(numbers[i])) { duplication[0] = numbers[i]; flag = true; break; } map.put(numbers[i], null); } return flag; } }
有一個條件咱們沒有用到,就是數據的範圍是 0 ~ n-1,因此咱們能夠這麼作:函數
/* * 返回描述: * 若是數組中有重複的數字,函數返回true,不然返回false * 若是數組中有重複的數字,把重複的數字放到參數duplication[0]中 */ public class Solution { public boolean duplicate(int numbers[],int length,int [] duplication) { for(int i = 0; i < length; i++) { // 不相等就一直交換 if(i != numbers[i]) { if(numbers[i] != numbers[numbers[i]]) { int temp = numbers[numbers[i]]; numbers[numbers[i]] = numbers[i]; numbers[i] = temp; } else { duplication[0] = numbers[i]; return true; } } } return false; } }
仍是以前的條件,數據的範圍是 0 ~ n-1,因此能夠利用現有數組設置標誌,當一個數字被訪問事後,能夠設置對應位上的數 + n,以後再遇到相同的數時,會發現對應位上的數已經大於等於n了,那麼直接返回這個數便可指針
/* * 返回描述: * 若是數組中有重複的數字,函數返回true,不然返回false * 若是數組中有重複的數字,把重複的數字放到參數duplication[0]中 */ public class Solution { public boolean duplicate(int numbers[],int length,int [] duplication) { if(numbers == null || numbers.length == 0) { duplication[0] = -1; return false; } for(int i = 0; i < numbers.length; i++) { // 獲得當前正在遍歷的數 int index = numbers[i]; // index 有可能已被改變,爲了找到正確的對應數組位置,必須減去length if(index >= length) { index -= length; } // 對應位置若是大於length,則爲重複數字 if(numbers[index] >= length) { duplication[0] = index; return true; } numbers[index] += length; } return false; } }