數組中重複的數字


在一個長度爲 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,因此咱們能夠這麼作:函數

  • 設置一個指針 i 指向開頭 0
  • 對於 arr[i] 進行判斷,若是 arr[i] == i,說明下標爲 i 的數據正確的放在了該位置上,讓 i++
  • 若是 arr[i] != i,說明沒有正確放在位置上,那麼咱們就把 arr[i] 放在正確的位置上,也就是交換 arr[i] 和 arr[arr[i]]。交換以後,若是 arr[i] != i,繼續交換
  • 若是交換的過程當中,arr[i] == arr[arr[i]],說明遇到了重複值,返回便可
/*
 * 返回描述:
 * 若是數組中有重複的數字,函數返回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;
    }
}
相關文章
相關標籤/搜索