面试题3(二):不修改数组找出重复的数字

// 面试题3(二):不修改数组找出重复的数字
// 题目:在一个长度为n+1的数组里的所有数字都在1到n的范围内,所以数组中至
// 少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的
// 数组。例如,如果输入长度为8的数组{2, 3, 5, 4, 3, 2, 6, 7},那么对应的
// 输出是重复的数字2或者3。

解题思路:

不能修改数组,可以创建一个长度为n+1的辅助数组,空间复杂度为O(n)。

如果用时间换空间的话,可以使用二分查找的思想。

元素范围为1~n,但是有n+1个元素,说明有某个数字重复了。

以中间数字m为界限,分成两部分,1~m和m+1~n。

如果1~m的元素个数超过了m,说明重复元素在前半部分,再次划分1~m。

重复此过程,直到最后找出重复元素。

伪代码:

if(输入参数无效)
    return -1;
int start=1;
int end=length-1;
while(start<=end){
    int middle=区间中点;
    int count=start到middle之间元素个数;
    if(区间上下限相等){
        if(count大于1)
            return start;
        else
            return -1;
    }

    if(count>(middle-start+1))
        end=middle;
    else
        start=middle+1;
}
return -1;

c/c++代码:

int getDuplication(const int* numbers,int length){
    //校验输入参数的有效性
    if(numbers==nullptr||length<0){
        return -1;
    }
    for(int i=0;i<length;i++){
        if(numbers[i]<1||numbers[i]>length-1){
            return -1;
        }
    }

    //二分查找重复元素
    int start=1;
    int end=length-1;
    while(end>=start){
        int middle=((end-start)>>1)+start;
        int count=countRange(numbers,length,start,middle);
        //区间上下限相等
        if(end==start){
            //元素数量大于1,成功查找
            if(count>1)
                return start;
            else
                break;
        }

        //区间上下限不等,继续二分查找
        if(count>(middle-start+1))
            end=middle;
        else
            start=middle+1;
    }
    return -1;
}
//获取区间元素个数
int countRange(const int* numbers,int length,int start,int middle){
    if(numbers==nullptr||length<0){
        return -1;
    }

    int count=0;
    for(int i=0;i<length;i++){
        if(numbers[i]>=start&&numbers[i]<=middle)
            count++;
    }
    return count;
}

参考资料:

剑指offer面试题3(二)

原文地址:https://www.cnblogs.com/BoqianLiu/p/9404517.html

时间: 2024-10-20 15:43:47

面试题3(二):不修改数组找出重复的数字的相关文章

一起来刷《剑指Offer》——不修改数组找出重复的数字(思路及Python实现)

数组中重复的数字 在上一篇博客中<剑指Offer>-- 题目一:找出数组中重复的数字(Python多种方法实现)中,其实能发现这类题目的关键就是一边遍历数组一边查满足条件的元素. 然后我们在博客用最复杂的方式学会数组(Python实现动态数组)这篇博客中介绍了数组这一结构的本质,并自己动手实现了一个动态数组. 今天我们介绍一下另一道来自<剑指Offer>的关于数组的面试题--不修改数组找出重复的数字. 不修改数组找出重复的数字 题目二:不修改数组找出重复的数字 给定一个长度为 n+

[题目2]不修改数组找出重复的数字

代码实现: package j2; /** * 不修改数组找出重复的数字 * Created by admin on 2019/5/14. */ public class FindDuplicate3 { public static void main(String[] args) { int arr[] = {2,3,5,4,3,2,6,7}; System.out.println(duplicate(arr,arr.length)); } public static int duplicat

不修改数组找出重复的数字(c语言)

让人瑟瑟发抖的面试题... 来我们看一下题目在一个 长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的.请找出数组中任意一个重复的数字,但不能修改输入的数组.注意:时间复杂度O(n),空间复杂度O(1) 找出数组中重复的数字(c语言)怎么解决勒???分析:利用题目中元素处于1~n的范围,把元素分为两组,判断两组元素个数,如果大于范围,则重复的数字就在这个范围内.例如:1~3范围中有4个数,说明其中至少有一个重复的数字.按此二分下去,将会剩下一个数字有两个,最后输出

不修改数组找出重复的数字

在一个长度为n+1的数组里的所有数字都在1到n的范围内,所以数组中至少有一个数字是重复的. 请找出数组中任意一个重复的数字,但不能修改输入的数组. 例如,如果输入长度为8的数组{2, 3, 5, 4, 3, 2, 6, 7},那么对应的输出是重复的数字2或者3. 思路 按照二分查找的思路 数组长度为n+1,而数字只从1到n,说明必定有重复数字. 可以用二分查找扩展{2, 3, 5, 4, 3, 2, 6, 7} 取中间数4 统计1-4,5-7 在数组出现的次数 1-4 出现了5次,如果大于4则在

2017头条笔试题:二维点集中找出右上角没有点的点并按x坐标从小到大打印坐标

PS:这篇是之前本来就想发的但是一直没时间写,加上今天做了京东的题,结果代码名就命名为jingdong了--懒得改代码名重新跑一遍结果了=.= 暴力法去做就是遍历每个点,判断它是不是"最大点".判断过程则是又遍历一遍,看看是否存在其他点在它右上方,若存在则不是最大点.O(N^2) 但是这样就会有很多不必要的计算,举个例子(这里暂且当坐标都是int),若存在一个最大点(x0,y0),那么所有在它左下角的点都不用考虑了. 另外,对于(x0,y0),只需要查找在它右边(x>x0)的点是

2015年 【华为c++技术面试题】找出重复的数字

面试题目: 1-100共100个数,外加一个重复的数字,共101个:这101个数是乱序的,让你找出这个重复的数字: 解题思路: 这个重复的数=这101个数的和-5050(1-100的和): C++代码: 结果展示:

数组a[n]中存放1-n中的n-1个数,给出算法找出重复的那一个数

问题描述: 数组a[n]中存放1-n中的n-1个数,给出算法找出重复的那一个数. 算法一: 对数组a[n]进行冒泡排序,如果冒泡所得的最值和前一个最值相等,则该最值为重复的数. 分析: 该算法时间复杂度最坏的情况为O(n的2次方),在空间开销上只需要一个额外的交换空间. 如何将时间开销减小呢?下面给出另外一种算法 算法二: 给定另外一个数组b[n],将a[n]中的数作为数组b的索引,然后遍历b[n],如果未访问过,则标记:如果已经访问过,则该索引就为重复的数. 分析: 该算法时间复杂度能够达到最

锦程网考试由试题从模拟题中批量找出答案,Python

jincin的考试又来了,像往常一样会先有模拟题发下来,而考试题目几乎都在里面原题. 本来是,在考试时,把题目一题一题地在模拟题里搜,但觉得太累了. 于是写了一个Python的脚本批量查找,用到正则,由于不知道行尾是\r还是\n还是\r\n,干脆也用正则,而非split('\r')这么硬板了. 添了颜色,效果不错. Python: 效果: - 锦程网考试由试题从模拟题中批量找出答案,Python,布布扣,bubuko.com

两个有序数组找出相同数据

两个有序数组找出相同数据,要求最简单的算法复杂度. class Program { static void Main(string[] args) { int Low = 0; int[] m = new int[] { 2, 4, 6, 9, 12, 13, 15, 16 }; int[] n = new int[] { 3, 5, 9, 12, 15 }; foreach (int item in m) { Search(n, ref Low, n.Length - 1, item); }