zoukankan      html  css  js  c++  java
  • 面试宝典-面试题3.2:不修改数组找出重复的数字

    一、题意:长度为n+1的数组里的所有数字都在1~n的范围内,找出任意一个重复复的数字,但不能修改原数组。

    二、思路:

      1、创建一个长度为n+1的辅助数组,在O(n)的复杂度里面可以解决这个问题,空间复杂度也为O(n);

      2、时间换空间,采用类似于二分查找的方式,用中间数字对数组中的数字进行划分,然后在最后某个长度为1的空间中总能找到一个重复数字。这种方法时间复杂度为O(nlogn),但空间复杂度为O(1);

    三、代码:

     1 #include"iostream"
     2 #include"stdio.h"
     3 using namespace std;
     4 const int MAXN=1000;
     5 
     6 int CountRange(const int * numbers,int length,int start ,int end)
     7 {
     8     if(numbers==nullptr)
     9         return 0;
    10     int count=0;
    11     for(int i=0;i<length;i++)
    12         if(numbers[i]>=start&&numbers[i]<=end)
    13             ++count;
    14     return count;
    15 }
    16 
    17 int GetDuplication(const int * numbers,int length)
    18 {
    19     if(numbers==nullptr || length<=0)
    20         return -1;
    21 
    22     int start=1;
    23     int end=length-1;
    24     while(end>=start)
    25     {
    26         int middle=((end-start)>>1)+start;//求平均值的良好 习惯
    27         int count=CountRange(numbers,length,start,middle);
    28         if(end==start)
    29         {
    30             if(count>1) return start;
    31             else break;
    32         }
    33         if(count>(middle-start)+1)
    34             end=middle;
    35         else
    36             start=middle+1;
    37     }
    38     return -1;
    39 }
    40 
    41 int main()
    42 {
    43     int length;
    44     while(cin>>length)
    45     {
    46         int numbers[MAXN];
    47         for(int i=0;i<length;i++)
    48             cin>>numbers[i];
    49         int res=GetDuplication(numbers,length);
    50         if(res!=-1)
    51             cout<<"the duplicate number is: "<<res<<endl;
    52         else
    53             cout<<"wrong input!"<<endl;
    54     }
    55     return 0;
    56 }
    View Code

     官方答案,真的是好严谨。差距很大。。。

    #include <iostream>
    
    int countRange(const int* numbers, int length, int start, int end);
    
    // 参数:
    //        numbers:     一个整数数组
    //        length:      数组的长度
    // 返回值:
    //        正数  - 输入有效,并且数组中存在重复的数字,返回值为重复的数字
    //        负数  - 输入无效,或者数组中没有重复的数字
    int getDuplication(const int* numbers, int length)
    {
        if(numbers == nullptr || length <= 0)
            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)
            {
                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 end)
    {
        if(numbers == nullptr)
            return 0;
    
        int count = 0;
        for(int i = 0; i < length; i++)
            if(numbers[i] >= start && numbers[i] <= end)
                ++count;
        return count;
    }
    
    // ====================测试代码====================
    void test(const char* testName, int* numbers, int length, int* duplications, int dupLength)
    {
        int result = getDuplication(numbers, length);
        for(int i = 0; i < dupLength; ++i)
        {
            if(result == duplications[i])
            {
                std::cout << testName << " passed." << std::endl;
                return;
            }
        }
        std::cout << testName << " FAILED." << std::endl;
    }
    
    // 多个重复的数字
    void test1()
    {
        int numbers[] = { 2, 3, 5, 4, 3, 2, 6, 7 };
        int duplications[] = { 2, 3 };
        test("test1", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int));
    }
    
    // 一个重复的数字
    void test2()
    {
        int numbers[] = { 3, 2, 1, 4, 4, 5, 6, 7 };
        int duplications[] = { 4 };
        test("test2", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int));
    }
    
    // 重复的数字是数组中最小的数字
    void test3()
    {
        int numbers[] = { 1, 2, 3, 4, 5, 6, 7, 1, 8 };
        int duplications[] = { 1 };
        test("test3", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int));
    }
    
    // 重复的数字是数组中最大的数字
    void test4()
    {
        int numbers[] = { 1, 7, 3, 4, 5, 6, 8, 2, 8 };
        int duplications[] = { 8 };
        test("test4", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int));
    }
    
    // 数组中只有两个数字
    void test5()
    {
        int numbers[] = { 1, 1 };
        int duplications[] = { 1 };
        test("test5", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int));
    }
    
    // 重复的数字位于数组当中
    void test6()
    {
        int numbers[] = { 3, 2, 1, 3, 4, 5, 6, 7 };
        int duplications[] = { 3 };
        test("test6", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int));
    }
    
    // 多个重复的数字
    void test7()
    {
        int numbers[] = { 1, 2, 2, 6, 4, 5, 6 };
        int duplications[] = { 2, 6 };
        test("test7", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int));
    }
    
    // 一个数字重复三次
    void test8()
    {
        int numbers[] = { 1, 2, 2, 6, 4, 5, 2 };
        int duplications[] = { 2 };
        test("test8", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int));
    }
    
    // 没有重复的数字
    void test9()
    {
        int numbers[] = { 1, 2, 6, 4, 5, 3 };
        int duplications[] = { -1 };
        test("test9", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int));
    }
    
    // 无效的输入
    void test10()
    {
        int* numbers = nullptr;
        int duplications[] = { -1 };
        test("test10", numbers, 0, duplications, sizeof(duplications) / sizeof(int));
    }
    
    int main()
    {
        test1();
        test2();
        test3();
        test4();
        test5();
        test6();
        test7();
        test8();
        test9();
        test10();
        return 0;
    }
    View Code
  • 相关阅读:
    React Native 项目常用第三方组件汇总
    react-native-swiper的Github地址
    Navicat for MySQL 使用
    maven项目创7 配置分页插件
    rander()函数执行条件
    RN生命周期
    react-native连接夜神模拟器
    让PHP7达到最高性能的几个Tips
    php安装
    被swoole坑哭的PHP程序员
  • 原文地址:https://www.cnblogs.com/acm-jing/p/10349784.html
Copyright © 2011-2022 走看看