剑指offer面试题3——找到数组中重复的数

题目:
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

思路:
方法一:两个for循环,用vector存储重复的数,可输出所有数字和重复次数。时间复杂度O(n^2)
方法二:先排序,然后顺序查找。(先排序再查找,参考排序代码)
方法三:使用哈希表,记录关键字及记录出现的次数
方法四:注意:数组元素范围在0~n-1之间。因此,若没有重复的数字,则所有的元素排序后,数字i将出现在下标为i的位置。若有重复,可能有一些位置没有元素,一些位置有多个。利用这种方法,依次扫描每个数字,①判断是否和对应下标相等?相等,i++;不相等,判断num[i]是否和以num[num[i]]相等?若不相等,则交换;若相等,则找到第一个重复的元素。

/************************************************************************/
/*      剑指offer3:数组中重复的数字                                          */
/************************************************************************/

#include
#include 
#include 
#include 
#include 
using namespace std;


/************************************************************************/
/*      第一种方法:两个for循环遍历,然后用vector向量记录重复数字和次数:时间复杂度O(N^2)                    */
/************************************************************************/
void iterateNum1()
{
    int a[]={2,3,1,0,2,5,3,0};
    int len=sizeof(a)/sizeof(a[0]);

    vector<int> Result;

//  hash_mapm;

    for (int i=0;iint count=0;
        int n;
        for (int j=0;jif (a[i]==a[j])
            {
                count++;
                n=i;
            }
        }
    if (count>1)
    {
        Result.push_back(a[n]);
    }

    }

    for (int i=0;i2;i++)
    {
        cout</************************************************************************/
/*          第二种方法:用哈希表           时间复杂度O(n) ;空间需要一个大小为O(n)的哈希表       */
/************************************************************************/

#include 
#include 
void iterateNum2_hash()
{
    int a[8]={2,3,1,0,2,5,3,0};
    int len=sizeof(a)/sizeof(a[0]);

    hash_map<int,int>m;
    int count=0;

    for (int i=0;i//遍历关联容器
    while(map_it != m.cend())
    {
        if (map_it->second >1)
        {
        cout<first<second<else
            ++map_it;       
    }
}

/************************************************************************/
/*      方法三:数字范围在0~n-1之间,则下标i是否对应数字m?对应,扫描下一个;不对应,和第m个位置数字相比?相等,重复;不等,交换到对应位置               */
/************************************************************************/
bool duplicate(int numbers[], int length, int *duplication)
{
    //首先判断边界条件
    if (numbers==nullptr || length<=0)
        return false;

    for (int i=0;iif (numbers[i]<0 || numbers[i]>length-1)
            return false;
    }

    for(int i=0;iwhile(numbers[i]!=i)
        {
            //while循环一直进行,i和num[i]不相等就一直交换,直到找到第一个重复的数。
            if (numbers[i]==numbers[numbers[i]])
            {
                *duplication =numbers[i];
                return true;
            }
            //不相等的话,交换两个数据
            int temp=numbers[i];
            numbers[i]=numbers[temp];
            numbers[temp]=temp;

        }
    }

    return false;


}
//===========测试代码============
bool contains(int array[], int length, int number)
{
    for (int i=0;iif (array[i]==number)
        {           
            cout<return true;
        }
    }
    return false;
}

void test(char* testName, int numbers[], int lengthNnumbers, int expected[],int expectedExpected, bool validArgument)
{
    printf("%s begins:\n",testName);

    int duplication;
    bool validInput = duplicate(numbers, lengthNnumbers,&duplication);
    if (validArgument == validInput)
    {
        if (validArgument)
        {
            if (contains(expected,expectedExpected,duplication))
            {
                printf("passed.\n");
            }
            else
                printf("failed.\n");
        }

        else
            printf("passed.\n");
    }
    else
        printf("failed.\n");

}

//重复数字是数组中最小的数字
void test1()
{
    int numbers[]={2,1,3,1,4};
    int duplications[]={1};
    test("test1",numbers,sizeof(numbers)/sizeof(int),duplications,sizeof(duplications)/sizeof(int),true);
}

//重复数字是数组中最大的数
void test2()
{
    int numbers[]={2,4,3,1,4};
    int duplications[]={4};
    test("test2",numbers,sizeof(numbers)/sizeof(int),duplications,sizeof(duplications)/sizeof(int),true);

}

//多个重复的数字
void test3()
{
    int numbers[]={2,4,3,2,4};
    int duplications[]={2,4};
    test("test3",numbers,sizeof(numbers)/sizeof(int),duplications,sizeof(duplications)/sizeof(int),true);
}

//没有重复数字
void test4()
{
    int numbers[]={1,2,3,4,5};
    int duplications[]={-1};
    test("test4",numbers,sizeof(numbers)/sizeof(int),duplications,sizeof(duplications)/sizeof(int),false);

}

//无效的输入
void test6()
{
    int *numbers=NULL;
    int duplications[]={-1};
    test("test6",numbers,0,duplications,sizeof(duplications)/sizeof(int),false);
}

int main()
{
    test1();
    test2();
    test3();
}

你可能感兴趣的:(C++,剑指offer笔记)