【劍指offer】數組中重複的數字

題目

在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內。 數組中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出數組中任意一個重複的數字。 例如,如果輸入長度爲7的數組{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字2

題解

一、排序

1. 分析

將輸入數組排序,再判斷相鄰位置是否存在相同數字,如果存在,對 duplication 賦值返回,否則繼續比較

2. 代碼

import java.util.*;
public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers == null || length == 0){
            return false;
        }
        Arrays.sort(numbers);
        for(int i=0;i<length-1;i++){
            if(numbers[i] == numbers[i+1]){
                duplication[0] = numbers[i];
                return true;
            }
        }
        return false;
    }
}

3. 複雜度

時間複雜度:O(nlogn)O(nlogn)
空間複雜度:O(1)O(1)

二、哈希表

1. 分析

利用 HashSet 解決,從頭到尾掃描數組,每次掃描到一個數,判斷當前數是否存在 HashSet 中,如果存在,則重複,對 duplication 賦值返回,否則將該數加入到 HashSet 中

2. 代碼

import java.util.*;
public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        Set<Integer> set = new HashSet<>();
        for(int i =0 ;i<length;i++){
            if(set.contains(numbers[i])){
                duplication[0] = numbers[i];
                return true;
            }else{
                set.add(numbers[i]);
            }
        }
        return false;
    }
}

3. 複雜度

時間複雜度:O(n)O(n)
空間複雜度:O(n)O(n)

三、利用特性

1. 分析

數組的長度爲 n 且所有數字都在 0 到 n-1 的範圍內,我們可以將每次遇到的數進行"歸位",當某個數發現自己的"位置"被相同的數佔了,則出現重複。
掃描整個數組,當掃描到下標爲 i 的數字時,首先比較該數字(m)是否等於 i,如果是,則接着掃描下一個數字;如果不是,則拿 m 與第 m 個數比較。如果 m 與第 m 個數相等,則說明出現重複了;如果 m 與第 m 個數不相等,則將 m 與第 m 個數交換,將 m “歸位”,再重複比較交換的過程,直到發現重複的數

舉個栗子:
以數組 {2,3,1,0,2,5,3} 爲例
當 i = 0 時,nums[i] = 2 != i,判斷 nums[i] 不等於 nums[nums[i]],交換 nums[i] 和 nums[nums[i]],交換後數組爲:{1,3,2,0,2,5,3}
此時 i = 0,nums[i] = 1 != i,判斷 nums[i] 不等於 nums[nums[i]],交換 nums[i] 和 nums[nums[i]],交換後數組爲:{3,1,2,0,2,5,3}
此時 i = 0,nums[i] = 3 != i,判斷 nums[i] 不等於 nums[nums[i]],交換 nums[i] 和 nums[nums[i]],交換後數組爲:{0,1,2,3,2,5,3}
此時 i = 0,nums[i] = 0 = i,繼續下一組
當 i = 1,nums[i] = 1 = i,繼續下一組
當 i = 2,nums[i] = 2 = i,繼續下一組
當 i = 3,nums[i] = 3 = i,繼續下一組
當 i = 4,nums[i] = 2 != i,判斷 nums[i] 等於 nums[nums[i]],出現重複,賦值返回

2. 代碼

import java.util.*;
public class Solution {
    public boolean duplicate(int nums[],int length,int [] duplication) {
        if(nums == null || length == 0){
            return false;
        }
        for(int i=0;i<length;i++){
            while(nums[i] != i){
                if(nums[i] == nums[nums[i]]){
                    duplication[0] = nums[i];
                    return true;
                }
                // swap
                int tmp = nums[i];
                nums[i] = nums[tmp];
                nums[tmp] = tmp;
            }
        }
        return false;
    }
}

3. 複雜度

時間複雜度:O(n)O(n)
空間複雜度:O(1)O(1)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章