《剑指offer》.2:不修改数组找到重复的数字

题目简介:

和之前那个题目差不多,但之前那个是用的修改数组的方法,此题目限制不能修改数组,所以我们需要寻找更好的方法。

题目分析:

其实就是给定一个数组,数组中包含重复元素,我们需要想一些方法来解决如何找到这些重复元素

解题思路:

在没有翻阅书籍前,暂时只能想出创建哈希表的方式,通过遍历哈希表来找到重复数字。书中介绍的类似二分查找,简单而言就是多次统计数字出现次数。在一个长度为n+1的数组中存在0-n的数字一定会存在一个或者多个重复数字,所以我们就可以利用这个特点,我们可以先找到0-n的中间值,通过中间值来把这个数字组分成两个部分,(0,n/2】和(n/2+1,n】,如果某一个范围内存在的的数字个数超过其最大值,则一定存在重复数字,一轮轮统计就一定能找到重复数字。也就是说例如数组:{2,3,5,4,3,2,6,7},先把这个数组分成1-4和5-7两个范围,统计这两个范围内的数字有几个,1-4有五个数字,所以一定存在重复数字,5-7只有三个所以下一阶段就是再把1-4分为1-2和3-4,就这样就可以一步步统计出重复的数字是哪个。

代码实现:

int countRange(const int *nums, int length, int start, int end)
{
    if(nums == NULL)
        return 0;
    
    int count = 0;
    for(int i=0; i<length; i++)
    {
        if(nums[i]>=start && nums[i]<=end)
            ++count;
    }
    return count;
}
 
int getDuplication(const int *nums, int length)
{
    if(nums == NULL || length <= 0)
        return -1;
    
    int start = 1;
    int end = length - 1;
    
    while(start <= end)
    {
        int mid = (start+end)/2;
        int count = countRange(nums, length, start, mid);
        if(start == end)
        {
            if(count > 1)
                return start;
            else
                break;
        }
        
        if(count > (mid - end + 1))  
            end = mid;
        else                      
            start = mid + 1;
    }
    
    return -1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值