1. 程式人生 > 實用技巧 >劍指 Offer 53 - II. 0~n-1中缺失的數字(C++)

劍指 Offer 53 - II. 0~n-1中缺失的數字(C++)

目錄

題目

一個長度為n-1的遞增排序陣列中的所有數字都是唯一的,並且每個數字都在範圍0~n-1之內。在範圍0~n-1內的n個數字中有且只有一個數字不在該陣列中,請找出這個數字。

示例1:

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

示例2:

輸入: [0,1,2,3,4,5,6,7,9]
輸出: 8

限制:

1 <= 陣列長度 <= 10000

分析與題解

題解一

假設 0~n-1 中沒有數字 i ,那麼這 n - 1 個數字的和為 sum = n(n-1)/2 - i,那麼 i = n(n-1)/2 - sum。

程式碼如下:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int size = nums.size();
        int sum=0;
        for(int i=0;i<size;i++)
        {
            sum+=nums[i];
        }
        int total = (1+size)*(size)/2;
        return (total-sum);
    }
};

題解二

因為要不重複地將0~n-1填入到n-1個空位中,所以首個下標與陣列元素不等的位置,缺失的數值與當前下標相等。如果遍歷陣列後,所有下標都與其對應的陣列元素相等,那麼缺失的元素即為n-1。程式碼如下:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int size = nums.size();
        for(int i=0;i<size;i++)
        {
            if(nums[i]!=i)
                return i;
        }
        return size;
    }
};

題解三

上述倆題解的時間複雜度均為 O(n)。與題解二類似,同樣依賴於整個陣列元素按照遞增序列進行排序的。如果任意下標i與其對應陣列元素相等,那麼缺失的元素一定在i+1到n-1之間;如果不等,則缺失的數字在0~i之間。因此採用二分查詢法思想去優化時間複雜度。

若i==nums[i],則下標i左邊只有0~i-1可以使用,並且空位總數為i,又需要按照遞增排序,所以位置確定無二義性

程式碼如下:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int mid=0,left=0;
        int right=nums.size();
        while(left<right)
        {
            mid = (left+right)/2;
            if(nums[mid]==mid)
            //不確定是否為第一個下標不等的元素
            {
                left = mid+1;
            }
            else
            {
                right=mid;
            }
        }
        return left;
        //最後左右邊界重合,輸出任意一個邊界
    }
};