Algorithm questions of arrays from shallow to deep (vs: chatGPT as algorithm)

background

As the saying goes, learn the new by reviewing the old. The effect of chatGPT is amazing! It is simply the effect of crushing. But there is still hope, pick it up first, and then innovate. Understand first, then go beyond.

ps: Brush up the algorithm question ideas for the last time. By the way, feel the magic of the big model based on chatGPT3.5.

The difference between array and pointer

In C/C++, arrays and pointers are two concepts that are both related and distinct. When we declare an array, its array name is also a pointer, which points to the first element of the array. We can access the array through a pointer, but C/C++ does not record the size of the array, so when using a pointer to access the elements in the array, the programmer must ensure that the boundary of the array is not exceeded.

The difference between arrays and pointers. Run the code below, what is the output?

int GetSize(int data[])
{
    return sizeof(data);
}

int _tmain()
{
    int data1[]={1,2,3,4,5};
    int size1=sizeof(data1);

    int *data2=data1;
    int size2=sizeof(data2);

    int size3=GetSize(data1);

    printf("%d, %d, %d\n", size1, size2, size3);

}

The answer is to output "20, 4, 4".

data1 is an array, sizeof(data1) is to find the size of the array. This array contains 5 numbers, each integer occupies 4 bytes, so it takes up 20 bytes.

data2 is declared as a pointer, although it points to the first number of the array data1, it is still a pointer in essence. On a 32-bit system, the result of sizeof for any pointer is 4.

In C/C++, when an array is passed as a parameter of a function, the array automatically degenerates into a pointer of the same type. Therefore, although the parameter data of the function GetSize is declared as an array, it will degenerate into a pointer, and the result of size3 is still 4.

repeated numbers in array

Method 1 : Sort the input array and find the duplicate numbers from the sorted array. The time complexity of sorting an array of length n is O(nlogn).

Method 2 : Build a hash table, scan the array in turn, each time you scan a number, you can use O(1) time to determine whether the hash table already contains the number. The time complexity is O(n), but the space complexity of storing the hash table is O(n).

Method 3 : The number of the array is 0~n-1. If there is no repeated array, the number i is the position with the subscript i. If there are repeated numbers, there will be multiple numbers in a certain i position, and the answer has been found. Traversing the array, let each number have its own place.

Take the array {2,3,1,0,2,5,3} as an example.

{2,3,1,0,2,5,3}

{1,3,2, 0,2,5,3} The 0th position of the array is 2, the 2nd position of the array is 1, the values ​​of the two positions are interchanged

{3,1,2,0,2,5,3} The values ​​​​of positions 0 and 1 are swapped

{0,1,2,3,2,5,3} The values ​​at positions 0 and 3 are swapped

Positions 0, 1, 2, and 3 are all in their respective positions. After traversing to position 4, the value is 2, and there is already a 2 in the place where the subscript is 2, so there is a repetition, an answer is found, and the program exits .

The following is the implementation code of method 3. Although there is a double loop, each number can be exchanged at most twice to find its own position, so the total time complexity is O(n). In addition, all operations are performed directly on the input array without additional allocation of memory, so the space complexity is O(1).

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;
            }
            int temp=numbers[i];
            numbers[i]=numbers[temp];
            numbers[temp]=temp;

        }
    }
    return false;
}

Find duplicate numbers without modifying the array

Idea 1:

Create an auxiliary array of length n+1, and then copy each number of the original array to the auxiliary array one by one. If the number to be scaled in the original array is m, copy it to the subscript m of the auxiliary array. This makes it easy to find that number is a duplicate, but the scheme requires O(n) auxiliary space.

Idea 2:

Divide the numbers from 1~n into two parts from the middle number m, the first half is 1~m, and the second half is m+1~n. If the number of numbers from 1 to m exceeds m, then this half of the interval must contain repeated numbers; otherwise, the other half of the interval m+1~n must contain repeated numbers. We can continue to divide the interval of repeated numbers into two until we find a repeated number. This process is very similar to the binary search algorithm, except that there is an extra step to count the numbers in the interval.

Take the array {2,3,5,4,3,2,6,7} with a length of 8 as an example to analyze the search process. According to the meaning of the question, the length is 8 arrays and all the numbers are in the range of 1~7. The middle number 4 divides the range of 1~7 into two ends, one section is 1~4, and the other section is 5~7. Next, count the number of occurrences of the interval number 1~4, a total of 5 occurrences, so there must be repeated numbers in 1~4.

Next, divide the range of 1~4 into two, one section is 1,2 two numbers, and the other section is 3,4 two numbers. The number 1 or 2 appears twice. Count again that 3 or 4 appeared 3 times, which means that there must be a repetition of the two numbers 3 and 4. We then counted the number of occurrences of these two numbers, and then found that the number 3 appeared twice, which is a repetition numbers.

The above idea is implemented with the following code:

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

Idea 2 is based on the idea of ​​binary search. If the input length is an array of n, then the function countRange will be called O(logn) times, each time requiring O(n) time, so the total time complexity is O(nlogn) , the space complexity is O(1). Compared with the algorithm of O(n) auxiliary space in idea 1, it belongs to exchanging time for space.

It should be pointed out that the algorithm is not guaranteed to find all duplicate numbers.

Lookup in 2D array

In a two-dimensional array, each row is sorted in ascending order from left to right, and each column is sorted in ascending order from top to bottom. Please complete a function, input such a two-dimensional array and an integer, and judge Does the array contain the integer

For example, if you search for 7 in the following two-dimensional array, it returns true; if you search for 5, since the number is not included in the array, it returns false

[[1 2 8 9]

[2 4 9 12]

[4 7 10 13]

[6 8 11 15]]

Ideas :

You can first use the specific rectangle search process to find the law, and find that: first select the number in the upper right corner of the array, if the number is the number you want to find, then end the search; if the number is greater than the number you want to find, then remove the number where the number is located column; if the number is less than the number to be found, the row where the number is removed is eliminated. That is to say, if the number to be searched is not in the upper right corner of the array, one row or one column will be eliminated from the search range of the array each time, so that the search range can be narrowed at each step until the number to be searched is found, or the search range is null.

bool Find(int* matrix, int rows, int columns, int number)
{
    bool found = false;

    if(matrix != nullptr && rows > 0 && columns > 0)
    {
        int row = 0;
        int column = columns - 1;
        while(row < rows && column >=0)
        {
            if(matrix[row * columns + column] == number)
            {
                found = true;
                break;
            }
            else if(matrix[row * columns + column] > number)
                -- column;
            else
                ++ row;
        }
    }

    return found;
}

Easter eggs: chatGPT algorithm

Throwing this question to chatGPT, the comprehension ability is really too strong, the following is its answer:

Guess you like

Origin blog.csdn.net/u010420283/article/details/129374715