1. 程式人生 > >推斷數組中的反復元素

推斷數組中的反復元素

位置 tracking fin 推斷 find blog org math con

問題,有一個n+1個元素的數組。包括1到n的n個數,外加一個反復元素,將這個反復元素找出。

方法一:使用置換法,因為下標是從0開始,假設nums[i]==i+1,說明元素是放在正確的位置。繼續推斷。假設nums[i] == nums[nums[i]-1],說明nums[i]就是反復元素,是要求找到的,否則就轉換nums[i]和nums[nums[i]-1]

代碼例如以下:

class Solution
{
    public int findDuplicate(int[] nums)
    {
        if (0 == nums.length) return 0;

        for (int i = 0; i < nums.length;)
        {
            if (nums[i] == i + 1)
            {
                i++;
                continue;
            }

            if (nums[i] == nums[nums[i] - 1])
            {
                return nums[i];
            }

            int tmp = nums[i];
            nums[i] = nums[tmp - 1];
            nums[tmp - 1] = tmp;
        }

        return 0;
    }
}
方法二:取反法。在遍歷的過程中。將abs(nums[i])-1位置處的數據取反,在取反之前,假設為負,說明這個數是反復的

代碼例如以下:

class Solution
{
    public int findDuplicate(int[] nums)
    {
        if (0 == nums.length) return 0;

        for (int i = 0; i < nums.length; i++)
        {
            int tmp = Math.abs(nums[i]);

            if (nums[tmp - 1] < 0) return tmp;

            nums[tmp - 1] = -nums[tmp - 1];
        }

        return 0;
    }
}
方法三:用floyd判圈法。

由於有反復元素,終於會是一個環。

這樣的方法優點是不會改動數據元素(https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare)
代碼例如以下:

class Solution
{
    public int findDuplicate(int[] nums)
    {
        if (0 == nums.length) return 0;

        int slow = 0, fast = 0;

        slow = nums[slow];
        fast = nums[nums[fast]];

        while (slow != fast)
        {
            slow = nums[slow];
            fast = nums[nums[fast]];
        }

        fast = 0;
        while (slow != fast)
        {
            slow = nums[slow];
            fast = nums[fast];
        }

        return slow;
    }
}






推斷數組中的反復元素