劍指offer之陣列中重複的數字(Java實現)
阿新 • • 發佈:2019-01-07
1. 陣列中重複的數字
題目描述
在一個長度為 n 的數組裡的所有數字都在 0 到 n-1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字是重複的,也不知道每個數字重複幾次。請找出陣列中任意一個重複的數字。
Input:
{2, 3, 1, 0, 2, 5}
Output:
2
解題思路
要求複雜度為 O(N) + O(1),也就是時間複雜度 O(N),空間複雜度 O(1)。因此不能使用排序的方法,也不能使用額外的標記陣列。牛客網討論區這一題的首票答案使用 nums[i] + length 來將元素標記,這麼做會有加法溢位問題。
這種陣列元素在 [0, n-1] 範圍內的問題,可以將值為 i 的元素調整到第 i 個位置上。
以 (2, 3, 1, 0, 2, 5) 為例:
position-0 : (2,3,1,0,2,5) // 2 <-> 1 (1,3,2,0,2,5) // 1 <-> 3 (3,1,2,0,2,5) // 3 <-> 0 (0,1,2,3,2,5) // already in position position-1 : (0,1,2,3,2,5) // already in position position-2 : (0,1,2,3,2,5) // already in position position-3 : (0,1,2,3,2,5) // already in position position-4 : (0,1,2,3,2,5) // nums[i] == nums[nums[i]], exit
遍歷到位置 4 時,該位置上的數為 2,但是第 2 個位置上已經有一個 2 的值了,因此可以知道 2 重複。
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(nums, i, nums[i]);
}
}
return false;
}
private void swap(int[] nums, int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}