540. 有序数组中的单一元素

题目描述:

给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。

请你找出并返回只出现一次的那个数。

你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。

示例:

输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2
输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2

解答描述:

首先,该题明确要求时间复杂度为O(logn),空间复杂度为O(1),所以显然不能直接全部遍历,而要考虑二分法

其次,分析本题数组的特点,是一个有序数组,且除某个元素外,其余元素都出现两次;那么显然每个元素都是连续出现的,要么出现两次,要么出现一次,且数组的总个数为奇数个。

假设,数nums[x]为其中仅出现了一次的数,那么它左右两边都是成对的数,那么它一定处于奇数位,对应C语言的数组下标x必然为偶数

综上,我们仅考虑下标为偶数的元素,进行二分查找,初始化l=0,r=numsize-1;mid=(l+r)/2;(在这里,为了保持mid始终为偶数,对奇数mid进行-1)

如果nums[mid]==nums[mid+1],说明mid之前都成对,l向后跳两步;

否则,说明mid之前存在单个,r前移到mid处。

代码:

int singleNonDuplicate(int* nums, int numsSize){
    int l=0;
    int r=numsSize-1;
    int mid;
    while(l<r)
    {
        mid=(l+r)/2;
        if(mid%2==1)//保持mid为偶数
        {
            mid=mid-1;
        }

        if(nums[mid]==nums[mid+1])//说明mid之前都成对,l向后跳两步
        {
            l=mid+2;
        }
        else//说明mid之前存在单个,r前移到mid处
        {
            r=mid;
        }
    }
    return nums[l];
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值