机试(一)chapter2.4不修改数组输入查找重复数字

二分法经典模版

int start;

int end;

while(start<=end)

{

   int mid = (end-start1)>>2 + start;

//最终结果

if(start==end){ return start}

//结果前一段

if() { end = mid;)

//结果在后一段

else{ start = mid+1)

}

 

 

 

 

 

#include <iostream>
using namespace std;


/*
   不修改输入,查找数组中的重复数字 
   len n+1   数字1~n,共10种
   方法1:
        创建辅助数组a[n+1]   
        遍历原数组,假设第i个为m
        则a[m] = m
        若a[m]中已经有数字,则表示m是重复的数字
*/

/*
方法2:
        类似二分法
        把1~n值的数组从中间分为两段
        一段1~m,一段m+1~n
        若1~m中有重复的,则1~m总数>m
        若1~m中没有重复,则总数为m
            

            若1~m总数>1,则继续二分,循环判断,直到 段长度==1

*/

int countRegist(const int* nums, int length, int start, int end)
{
    if (nums == nullptr) return 0;
    int count = 0;
    for (int i = 0; i < length; i++)
    {
        if (nums[i] <= end && nums[i] >= start)
        {
            count++;
        }
    }
    return count;
}


bool judgeNum(int nums[], int length, int& num)
{

    //边界1
    if (length < 0|| nums==nullptr)
    {
        num = -1;
        return false;
    }
    //边界2
    for (int i = 0; i < length; i++)
    {
        if (nums[i] < 1 || nums[i] >= length)
        {
            num = -1;
            return false;
        }
    }


    //开始查找重复
    //找出1~n的中位数,存入m
    //即分成 1~m, 和 m+1~n两段
    int start = 1;
    int end = length - 1;
    while (start <= end)
    {
        //二分中间
        int mid = ((end - start) >> 1) + start;
        //统计1~m总共有多少个 
        int count = countRegist(nums, length, start, mid);
        
        //循环到最终的结果 start ==end 即 start~start有>=2个
        if (start == end)
        {

            if (count > 1)
            {
                num = start;
                return true;
            }
            else break;
        }
        
        if (count > (mid - start + 1))
        {
            //start~mid-1 (值)中有重复值
            end = mid;
        }
        else
        {
            //mid~end(值) 中有重复数字
            start = mid + 1;
        }      
    }
    return false;
}

int main()
{
    int nums[] = { 2,3,5,4,3,2,6,7 };
    int length = 8;
    int res = 0;
    judgeNum(nums, length, res);
    cout << res << endl;
    system("pause");
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值