1. 程式人生 > >[劍指Offer]陣列中重複的數字

[劍指Offer]陣列中重複的數字

題目描述:

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

思路一:

    根據題目描述,數組裡面的值範圍在0~n-1,此時就可以利用陣列的值作為我們陣列的下標,當陣列中存在重複的數字時,那它們就指向了同一個以該值為下標的陣列元素。利用這一點,我們在遍歷訪問陣列的時候,每訪問一個元素,將該元素值作為陣列元素下標,只要就指向了一個新的陣列元素,同時將這個新的元素值 + 陣列的長度length,如果此時新元素值>= 2 * length,說明在這之前已被更改過,也就說明存在重複數字。程式碼如下:
public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers == null){
            return false;
        }
        if(length != numbers.length){
            return false;
        }
        int index;
        for(int i = 0; i < length; i++){
            index = numbers[i];
            if(index >= length){
                index -= length;
            }
            numbers[index] += length;    //先更改一次
            if(numbers[index] >= 2 * length){
                duplication[0] = index;
                return true;
            }
        }
        return false;
    }

上面的的for迴圈也可以利用求餘的方法來實現,如下:
<span style="white-space:pre">	</span>for(int i = 0; i < length; i++){
            index = numbers[i];
            index = index % length;
            numbers[index] += length;
            if(numbers[index] >= 2 * length){
                duplication[0] = index;
                return true;
            }
      <span style="white-space:pre">	</span>}
時間複雜度為O(n),空間複雜度為O(1),但思路一這種方法的缺點就是,我們已經擅自改變了傳參過來的陣列元素內容

思路二:

    利用字串的一些特點來解題,如果一個字串中存在相同的字元,它們在字串中的位置肯定不一樣,那通過indexOf和lastIndexOf獲取到的索引值肯定就不同;反過來,如果字串中沒有相同的字元,那麼每個字元通過indexOf和lastIndexOf獲取到的索引值肯定相等。所以,我們的思路就是,先將陣列元素組拼成字串,然後利用上面的字串特點解題。程式碼如下:
public static boolean duplicate(int numbers[],int length,int [] duplication) {  
        if(numbers == null){  
            return false;  
        }  
        if(length != numbers.length){  
            return false;  
        }  
        StringBuilder sb = new StringBuilder();  
        for(int i = 0; i < length; i++){  
            sb.append("#").append(numbers[i]).append("#");//加入分隔符  
        }  
        String str = sb.toString();  
        for(int i = 0; i < length; i++){  
           if(str.indexOf("#" + numbers[i] + "#") != str.lastIndexOf("#" + numbers[i] + "#")){  
               duplication[0] = numbers[i];  
               return true;  
           }  
        }  
        return false;  
    }
這種方式的好處就是,我們沒有改變原來陣列的內容,但是額外增加了一個StringBuilder 。

思路三:

    類似思路一的思想,如果存在重複的數字,在遍歷過程中,通過陣列值作為陣列下標的過程中會指向同一個元素,單位了不改變原來的陣列,我們自己新增一個數組,存放boolean值,程式碼如下:
public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers == null){
            return false;
        }
        if(length != numbers.length){
            return false;
        }
        boolean[] flag = new boolean[length];  
        int index;
        for(int i = 0; i < length; i++){
           index = numbers[i];
           if(flag[index]){
               duplication[0] = numbers[i];
               return true;
           } 
           flag[index] = true;
        }
        return false;
    }
和思路二一樣,沒有改變原來陣列的內容,但是額外增加了一個數組變數。

相關推薦

offer-陣列重複數字

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

[Offer] 陣列重複數字(Python)

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

[Offer]陣列重複數字

題目描述:在一個長度為n的數組裡的所有數字都在0到n-1的範圍內。 陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意一個重複的數字。 例如,如果輸入長度為7

offer:陣列重複數字

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

offer--陣列重複數字

題目描述 在一個長度為n的數組裡的所有數字都在0到n-1的範圍內。 陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意一個重複的數字。 例如,如果輸入長度

offer——陣列重複數字

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

offer-陣列出現數字超過一半得數字

28.陣列中出現數字超過一半的數字 題目描述 陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。 解題思路:若陣列中有數字出現的

offer-陣列重複數字-不可改變輸入陣列(Java)

文章目錄 題目描述 示例 解析 題目描述 在一個長為n+1的數組裡的所有數字都在1~n的範圍內,所以陣列中至少有一個數字是重複的,請找出陣列中任意一個重複的數字,但不能修改輸入的陣列。 示例 輸入:

offer-陣列重複數字(Java)

文章目錄 題目描述 示例 解析 題目描述 在一個長度為n的數組裡的所有數字都在0到n-1的範圍內。 陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意一個重複的數字。

offer____陣列重複數字

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

offer50 陣列重複數字(java)

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

Offer 陣列唯一隻出現一次的數字

題目: 在一個數組中除了一個數字只出現一次之外,其他數字都出現了三次。請找出那個只出現一次的數字。你可以假設滿足條件的數字一定存在。 思考題: 如果要求只使用 O(n) 的時間和額外 O(1) 的空間,該怎麼做呢? 樣例 輸入:[1,1,1,2,2,2,3,4,4,4] 輸出:3 解

offer----陣列只出現一次的數字

題目描述 一個整型數組裡除了兩個數字之外,其他的數字都出現了偶數次。請寫程式找出這兩個只出現一次的數字。 //所有數字異或,最後得到的是兩個只出現一次的數字異或的結果,從低位到高位 //找到第一異或為1的位,記下來,根據這個位,將原來的陣列分做兩部分,可解 cl

offer----陣列出現次數超過一半的數字

陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。 思路一:排序 將數組裡元素從排序,然後用中間元素判

offer——陣列出現次數超過一半的數字(39題)

題目:陣列中有一個字出現的次數超過陣列長度的一半,請找出這個數字。例如,輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。 解題思想:一定要緊緊抓住輸出數字出現的次數超過陣列長度的一半,這一特性。

offer-陣列只出現一次的數字陣列

題目描述 一個整型數組裡除了兩個數字之外,其他的數字都出現了偶數次。請寫程式找出這兩個只出現一次的數字。 這題想到用map,類似於“陣列中出現次數超過一半的陣列”https://blog.csdn.net/Mr_xuexi/article/details/84555464 其中,data

offer-陣列出現次數超過一半的數字陣列

題目描述 陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。 看到這個就想到了c++中的map,C++中map提供的是一種鍵值對容器

[offer]陣列出現一半的數字

思路: 方法一: 用hashmap儲存數字以及出現的次數,遍歷陣列,找到該數字時就將value+1,在遍歷前判斷value值是否大於陣列長度的一半 方法二: 先對陣列排序,在陣列中間的數即為所求的數 實現: 方法一: import java.util.HashMap; public c

offer:陣列只出現一次的數字(java)

題目:一個整型數組裡除了兩個數字之外,其他的數字都出現了兩次。請些程式找出這兩個只出現一次的數字。要求時間複雜度為O(n),空間複雜度為O(1).     如輸入陣列{2,4,3,6,3,2,5,5},因為只有4,6這兩個數字只出現一次,其他數字都出現了兩次,所以輸出4

Offer - 陣列出現次數超過一半的數字(Java實現)

題目描述: 陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。 思路分析: 方法1:藉助HashMap,將數字