1. 程式人生 > >劍指offer之陣列中重複的數字(Java實現)

劍指offer之陣列中重複的數字(Java實現)

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; }