Note offer prove safety questions. 3 ---- plane array duplicate numbers

Topic one: find an array duplicate numbers. All numbers in an array of length n's are in the range of 0 ~ n-1. Some digital array is duplicated, but do not know how many numbers repeat, do not know each number was repeated several times. Please find an array of any one of the duplicate numbers. For example, if the length of the input array 7 {2, 3, 1, 0, 2, 5, 3}, then the corresponding output is repeatable number 2 or 3.

Test Case:

  • Array of length n contains one or more of the duplicate numbers.
  • Array does not contain duplicate numbers.
  • Input test invalid (null pointer input; array of length n contained in a number other than 0 ~ n-1)

Test code:

    void test(char* testName, int numbers[], int lengthNumbers, int expected[], int expectedExpected, bool validArgument)
    {
        printf("%s begins: ", testName);
        int duplication;
        bool validInput = duplicate(numbers, lengthNumbers, &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, 2, 1, 4 };
        int duplications[] = { 2, 4 };
        test("Test3", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), true);
    }
    
    // 没有重复的数字
    void test4()
    {
        int numbers[] = { 2, 1, 3, 0, 4 };
        int duplications[] = { -1 }; // not in use in the test function
        test("Test4", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false);
    }
    
    // 没有重复的数字
    void test5()
    {
        int numbers[] = { 2, 1, 3, 5, 4 };
        int duplications[] = { -1 }; // not in use in the test function
        test("Test5", numbers, sizeof(numbers) / sizeof(int), duplications, sizeof(duplications) / sizeof(int), false);
    }
    
    // 无效的输入
    void test6()
    {
        int* numbers = nullptr;
        int duplications[] = { -1 }; // not in use in the test function
        test("Test6", numbers, 0, duplications, sizeof(duplications) / sizeof(int), false);
    }

This question test sites:

  • Examine the candidates to understand that the array and programming skills. A continuous one-dimensional array occupies space in memory, so we can index the elements according to the corresponding positioning.
  • Examine the candidates ability to analyze problems. When the candidates found the problem more complicated, can not find out the rules by specific examples of them, it is the key to whether the solution to this problem.

solution:

  • First input sorted array, the array after scanning over again sort it. A sorting array of length n requires O (nlogn) time.
  • A hash table, the time complexity of O (n), the spatial complexity of O (n).
  • The optimal solution can be done time complexity of O (n), the spatial complexity is O (1).
    We note numbers in the array are in the range of 0 ~ n-1. If the array does not duplicate numbers, then after the next array sort numbers i to i marked location appears. Since the array has duplicate numbers, there may be some of the plurality of digital position, and some of these positions may not be digital.
    Now let's rearrange the array. From start to finish in order to scan the array in each number. When the scanning to the subscript i of the digital first comparator figure (denoted by m) is not equal to i. If yes, then scan the next number; if not, then let it compares the m-th digit. And if it is equal to the m-th digit, to find a repeatable number (this number is at index position i and m have appeared); and if it is not equal to the m-th digit, the i-th digit put and m digital exchange, into the position of the m belonging to it. Then repeat this comparison, the exchange process, knowing that we have found a duplicate number.
    Example:
    {2,. 3,. 1, 0, 2,. 5,. 3} -> {. 1,. 3, 2, 0, 2,. 5,. 3} -> {. 3,. 1, 2, 0, 2,. 5,. 3 } -> {0, 1, 2, 3, 2, 5, 3}

Implementation code:

    #include <cstdio>
    
    // 参数:
    //        numbers:     一个整数数组
    //        length:      数组的长度
    //        duplication: (输出) 数组中的一个重复的数字
    // 返回值:             
    //        true  - 输入有效,并且数组中存在重复的数字
    //        false - 输入无效,或者数组中没有重复的数字
    bool duplicate(int numbers[], int length, int* duplication)
    {
        if(numbers == nullptr || length <= 0)
            return false;
    
        for(int i = 0; i < length; ++i)
        {
            if(numbers[i] < 0 || numbers[i] > length - 1)
                return false;
        }
    
        for(int i = 0; i < length; ++i)
        {
            while(numbers[i] != i)
            {
                if(numbers[i] == numbers[numbers[i]])
                {
                    *duplication = numbers[i];
                    return true;
                }
                // 交换numbers[i]和numbers[numbers[i]]             
                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; i < length; ++i)
        {
            if(array[i] == number)
                return true;
        }
        return false;
    }
    int main()
    {
        test1();
        test2();
        test3();
        test4();
        test5();
        test6();
        return 0;
    }

Topic two: do not modify the array to find duplicate numbers. In an array of length n + 1, where all numbers are in the range of 1 ~ n, so that at least one number in the array is repeated. Please find an array of any one of the duplicate numbers, but can not modify the input array. For example, if the length of the input array of 8 {2, 3, 5, 4, 3, 2, 6, 7}, then the corresponding output is repeatable number 2 or 3.

Test Case:

  • An array of length n + 1 contains one or more of the duplicate numbers.
  • Array does not contain duplicate numbers.
  • Input test invalid (null pointer input; array of length n contained in a number other than n 1 ~).

Test code:

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));
}

This question test sites:

  • Examine the candidates to understand that the array and programming skills. Continuous array that occupies space in the memory, so we can index according to the corresponding element is positioned.
  • Examine the candidates understand the algorithm to find the half, and quickly and properly implement binary search algorithm in the code.
  • Examine the candidate's ability to communicate. Only candidates with good communication skills in order to fully understand the needs of the interviewer, which targeted selection algorithm to solve the problem.

Implementation 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 main()
{
    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
    test7();
    test8();
    test9();
    test10();
}

Guess you like

Origin www.cnblogs.com/tangliang39/p/11694438.html