有序數組的單一元素

題目

來源:力扣(LeetCode)
鏈接:有序數組的單一元素

分析

爲了分析方便,始終控制折半查找的子區間長度爲奇數。
設子區間爲[left,right]
mid=left+(right-left)/2
mid將子區間分爲兩個區間有如下幾種情況:

  • 因爲重複出現的元素兩兩配對,若[left,mid-1]區間長度爲偶數
    • nums[mid] ==numd[mid-1],則說明單一元素下標一定在[left,mid2][left,mid-2]中,且這一子區間長度爲奇數。如子序列112334455中 nums[mid]=numd[mid1]=3nums[mid]=numd[mid-1]=3,單一元素在左半區間。
    • nums[mid]==nums[mid+1],則說明單一元素一定在右半區間中,爲保證右半區間長度爲奇數,則left=mid+2如子序列112233455中 nums[mid]=numd[mid+1]=3nums[mid]=numd[mid+1]=3,單一元素在右半區間。
    • nums[mid]!=nums[mid+1]&&nums[mid]!=nums[mid-1]則返回nums[mid]
  • 若[left,mid-1]區間長度爲奇數,
    • nums[mid]==nums[mid-1],則說明單一元素一定在右半區間中.爲保證右半區間長度爲奇數,則更新left=mid+1。如子序列1122344中 nums[mid]=numd[mid1]=2nums[mid]=numd[mid-1]=2,單一元素在右半區間。
    • nums[mid]==nums[mid+1],則說明單一元素一定在左半區間中.爲保證左半區間長度爲奇數,則更新right=mid-1。如子序列1123344中 nums[mid]=numd[mid1]=3nums[mid]=numd[mid-1]=3,單一元素在左半區間。
    • nums[mid]!=nums[mid+1]&&nums[mid]!=nums[mid-1]則返回nums[mid]

代碼

int singleNonDuplicate(int* nums, int numsSize){
    if(numsSize==1) return nums[0];
    int left=0;
    int right=numsSize-1;
    int mid=0;
    
    while(left<right){
        mid=left+(right-left)/2;
        if(mid==0||mid==numsSize-1||nums[mid]!=nums[mid+1]&&nums[mid]!=nums[mid-1])
            return nums[mid];        
        int len=mid-left;
        if((len)%2==0){
            if(nums[mid]==nums[mid-1])
                right=mid-2;//保證子區間nums[left]~nums[right]長度爲奇數
            else
                left=mid+2;
        }else{
            if(nums[mid]==nums[mid-1])
                left=mid+1;
            else 
                right=mid-1; 
        }
    }
    return nums[left];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章