1. 程式人生 > 其它 >字串型別的內建方法(二)

字串型別的內建方法(二)

找出陣列中重複的數字。

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

方法1:雜湊表

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        vector<int> hashNum(nums.size(), 0); //雜湊表儲存數字出現的次數;
        for(auto x : nums){
            if(hashNum[x]) //出現了就返回;
                return x;
            hashNum[x]++; //沒出現就新增進去;
        }
        return -1;
    }
};

時間複雜度:$ O(n) $ ,空間複雜度:$ O(n)$

方法2:原地交換

將每一個數字放回到自己的位置,當掃描到下標為 \(i\) 的數字 \(num[i]\) 時,如果 $num[i]==i $,說明該數字放在了正確的位置上,否則的話看一下它本來應該在的位置 \(num[i]\) ,即 \(num[num[i]]\) 上的數字為多少,二者相等的話說明出現了重複,不相等的話就交換一下。

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int len = nums.size();
        for(int i = 0; i < len; i++){
            while(nums[i] != i){
                if(nums[i] == nums[nums[i]])
                    return nums[i];
                else
                    swap(nums[i],nums[nums[i]]);
            }
        }
        return -1;
    }
};

時間複雜度:$ O(n) $ ,空間複雜度:$ O(1)$

拓展題:不修改陣列找出重複的數字

在一個長度為n+1的陣列 nums 裡的所有數字都在 1~n 的範圍內。所以陣列中至少有一個數字是重複的。請找出陣列中任意一個重複的數字。

不修改陣列,不新增陣列,使用二分法。該方法不保證找到所有的重複數字,比如:{2,3,5,4,3,2,6,7}。

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int left = 1, right = nums.size() - 1;
        while(left <= right){
            int middle = ((right - left) >> 1) + left;
            int count = conutNums(nums, left, middle);

            if(left == right){
                if(count > 1)
                    return left;
                else
                    break;
            }

            if(count > (middle - left + 1))
                right = middle;
            else    
                left = middle + 1;
        }
        return -1;
    }

    int conutNums(vector<int>& nums, int left, int right){
        int count = 0;
        for(auto n : nums){
            if(n >= left && n <= right)
                count++;
        }
        return count;
    }
};