劍指offer 找出陣列中重複的數字

2022-06-28 15:21:09 字數 2162 閱讀 2281

在乙個長度為 n 的陣列 nums 裡的所有數字都在 0~n-1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。

示例 1:

輸入:

[2, 3, 1, 0, 2, 5, 3]

輸出:2 或 3

限制:2 <= n <= 100000

暴力求解的思路非常的直接:

**如下:

public int findrepeatnumber(int nums) }}

return -1;

}

以上演算法實現的複雜度分析:

細心的應該會發現這道題目描述的最後對 n 做了乙個限制,也就是:2 <= n <= 100000

那就是說,資料規模 n 有可能是 10 萬級別的,如果時間複雜度是 o(n^2) 的話,那麼資料規模就會變成 10 萬的平方了,這個級別就高了,所以上面的**的效能是非常差的。接下來我們來優化。

在暴力解法中,我們先遍歷每乙個元素,然後再從其餘的元素中查詢這個元素是否存在,其實這裡要的就是能高效的判斷乙個元素是否已經存在,我們可以使用雜湊表,因為雜湊表判斷是否存在的時間複雜度是 o(1)。

使用雜湊表後的演算法步驟是:

先初始化乙個雜湊表 (hashset)

然後遍歷每乙個元素,分別對每乙個元素做如下的處理:

先判斷雜湊表中是否存在這個元素

如果存在的話,則說明這個元素重複,則直接返回

否則,將這個元素加入到雜湊表中,方便後續的判重

**如下:

public int findrepeatnumber(int nums) 

​ // 否則的話,將當前元素放入到雜湊表中,方便後續的查詢判重

set.add(nums[i]);

}return -1;

}

以上演算法實現的複雜度分析:

時間複雜度 o(n),對於資料規模 10 萬級別的話,執行速度是可以接受的。但是這裡的空間複雜度則變為 o(n),因為雜湊表需要申請額外的 n 個空間,這裡用到的是典型的空間換時間的思想

在題目中,有乙個資訊,我們需要注意下,那就是陣列中每個元素的大小在 0 ~ n - 1 的範圍內。利用這個資訊,我們就可以使用陣列代替上面方案二的雜湊表,主要的思路是:

定義乙個長度為 n 的陣列 bucket,然後將所有的元素初始化為 -1

在查詢處理的時候,使用原陣列的元素作為 bucket 的下標,原陣列元素對應的下標作為 bucket 的元素值。

**:

public int findrepeatnumber(int nums) 

​ // 否則的話,將當前元素作為索引,當前元素的下標作為值,填入陣列中,

// 方便後續的查詢判重

bucket[nums[i]] = i;

}return -1;

}

以上演算法實現的複雜度分析:

時間複雜度是 o(n)

空間複雜度是 o(n)

可以看出,時間複雜度和空間複雜度都是和用雜湊表的解決方案是一樣的。但是使用陣列絕對會有效能的提高,主要表現在如下的兩個方面:

雜湊表 (hashset) 底層是使用陣列 + 鍊錶或者紅黑樹組成的,而且它的陣列也是用不滿的,有載入因子的。所以使用陣列來代替雜湊表,能節省空間

雜湊表在判重的時候需要經過雜湊計算,還可能存在雜湊衝突的情況,而使用陣列則可以直接計算得到 index 的記憶體位置,所以使用陣列訪問效能更好。

下面演算法的主要思想是把每個數放到對應的位置上,即讓 nums[i] = i。

public int findrepeatnumber(int nums) 

​ // 交換

int tmp = nums[nums[i]];

nums[nums[i]] = nums[i];

nums[i] = tmp;}}

return -1;

}

以上演算法實現的複雜度分析:

可以看出,我們利用這種方法,空間複雜度降到了 o(1) 了。

劍指offer 找出陣列中重複的數字

問題 在乙個長度為n的陣列裡的所有數字都在0 n 1的範圍裡,不知道重複的數字,也不知道每個重複數字重複幾次,找出陣列中所有重複的數字,如輸入,則應輸出。要求1 能改變陣列中的數字 思路1 將陣列排序,然後遍歷陣列,找出重複的數字。時間複雜度o nlogn 空間複雜度o 1 思路1的實現 vecto...

劍指offer 找出陣列中重複的數字

題目 在乙個長度為n的陣列裡的所有數字都在0 n 1的範圍內。陣列中某些數字是重複的,但是不知道有幾個數字重複了,也不知道每個數字重複了幾次,請找出陣列中任意乙個重複的數字。例如,如果輸入長度為7的陣列,那麼輸出的重複數字2或者3.分析 陣列中的數字為0 n 1的範圍內,如果再這個陣列中不存在重複的...

劍指offer 陣列 找出陣列中重複的數字

給定乙個長度為 n 的整數陣列 nums,陣列中所有的數字都在 0 n 1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。注意 如果某些數字不在 0 n 1 的範圍內,或陣列中不包含重複數字,則返回 1 樣例給定 nums 2...