1. 程式人生 > 其它 >劍指 Offer 03. 陣列中重複的數字-----原地交換

劍指 Offer 03. 陣列中重複的數字-----原地交換

題目表述

找出陣列中重複的數字。

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

示例 1:

輸入:
[2, 3, 1, 0, 2, 5, 3]

輸出:2 或 3

原地交換

題目給出,陣列nums長度為n,且數字範圍都在0~n-1的範圍內,並且有數字重複,所以下標和數字的對應關係應該是一對多的,可以通過遍歷陣列,將陣列的索引與值對應起。遍歷時,當地一次遇到數字i時,將其交換至索引i處,當第二次遇到數字i時,一定有nums[i] = i,此時便可以得到一組重複數字。

演算法流程:

  • 遍歷陣列 num ,設索引初始值為 i = 0:
    • 若 nums[i]=i : 說明此數字已在對應索引位置,無需交換,因此跳過;

    • 若 nums[nums[i]] = nums[i] :代表索引nums[i] 處和索引 i 處的元素值都為nums[i] , 即找到一組重複值,返回此值 nums[i];

    • 否則: 交換索引為 ii 和 nums[i]nums[i] 的元素值,將此數字交換至對應索引位置。

  • 若遍歷完畢尚未返回,則返回 -1。
class Solution {
    public int findRepeatNumber(int[] nums) {
        int n = nums.length;
        int i = 0;
        while(i < n){
            if(nums[i] == i){
                i++;
                continue;
            }
            if(nums[nums[i]] == nums[i]) return nums[i];
            int tmp = nums[i];
            nums[i] = nums[nums[i]];
            nums[tmp] = tmp;
        }
        return -1;
    }
}