Questions that I don't understand about sequence tables in linear tables

1. For a sequence table L of length n, write an algorithm with time complexity O(n) and space complexity O(1). This algorithm deletes all data elements whose value is x in the linear table.

My thoughts: time complexity is O(n), then there can only be one layer of loops. So it traverses directly from 0 to n-1, deletes any element whose value is equal to x, and moves the subsequent value forward. After implementing it, I discovered that the process of moving elements later is also a cyclic process, and if there are multiple x, multiple cycles are required to move.

The idea of ​​Wangdao Books: Traverse it from beginning to end, if it is not equal to x, put it in another array. This is a good line of thought to keep in mind.

void DeleteList(sqList *L, int x)
{
    int k = 0;
    for (int i = 0; i < L->length; i++)
    {
        if (L->data[i] != x)
        {
            L->data[k++] = L->data[i];
        }
        
    }
    L->length = k;
    
}

2. Title: Delete all elements whose values ​​are repeated from the ordered sequence table, so that all elements in the table have different values.

Analysis: mine: please see clearly: it is an ordered list! ! ! Don't always forget to see whether it is a sequential list or an ordered sequential list! Or take the strategy of copying to another ordered list. Put the different ones into another sorted list. It's just that I choose to compare side by side.

But what if it is 1 2 2 2 2 2 3 3 3 3 4 4 5?

Solution: Use an idea similar to direct insertion sorting , and initially treat the first element as a non-repeated ordered list. Then judge in turn whether the following elements are the same as the last element of the previous non-repeating ordered list. If they are the same, continue to judge backwards. If they are different, insert the last element of the previous non-repeating ordered list until the end of the list is judged. .

My code: It is to put the previous one for comparison into the sorted sequence, which will cause a problem. If the last element is not consistent with the previous one, there is no way to put it into the sorted sequence.

oid DeletedSm(sqList *L)
{
    int k = 0,i=0;
    for (int i = 0,j = 1; i < L->length; j++)
    {
       
        if (L->data[i] != L->data[j])
        {
            L->data[k++]=L->data[i];
            i = j;
        }
        if (i == L->length-1)
        {
            L->data[k]=L->data[i];
        }   
    }  
    L->length = K + 1;
}

The kingly way: it is to operate on the original sequence to be sorted, starting from the second element to see if it is consistent with the first element. Use the latter element to compare with the previous element, and store the latter. seconds! ! !

void DeletedSm(sqList *L)
{
    for (int i = 0,j=1; j < L->length; j++)
    {
       if (L->data[i] != L->data[j])
       {
         L->data[++i] = L->data[j];
       }
    }
}

3. Topic: Merge two ordered sequence tables into a new ordered sequence table, and return the result sequence table by the function.
算法思想:首先,按顺序不断取下两个顺序表表头较小的结点存入新的顺序表中。然后,看那个表还有剩余,将剩下的部分加到新的顺序表后面。(本算法的方法非常典型,需要牢固掌握)。

题目本身没有什么新奇的。就是在王道的代码里,我觉得要学一下这个点。

while (i < A->length && j < B -> length)
{
    if (A->data[i] <= B -> data[j])
    {
        C->data[k++] = A->data[i++];
        //直接在里面自加加,免得多写那么多趟代码。
    } 
}

4. The elements in the linear table (a1, a2, a3,...,an) are stored in the computer in an increasing order and in order. It is required to design an algorithm to complete the search for the element with the value x in the table in the least time. If found, it will be exchanged with the position of the subsequent element. If not found, it will be inserted into the table and the elements in the table will still be incremented. orderly.

Algorithm idea: The linear table stored sequentially is in increasing order, and can be searched sequentially or in half. The title requires: "Use the least amount of time to search for an element with value x in the table", then the half search method is recommended.

5、

算法的基本设计思想:
This problem can be regarded as converting the array ab into an array ba (a represents the first p elements of the array, b represents the remaining np elements in the array), first inverting a to get a(-1)b, and then converting b Invert to get a(-1)b(-1), and finally invert the entire a(-1)b(-1) to get ba. Time complexity: O(n), space complexity O(1).

I choose this ✅ Another solution: use auxiliary functions to achieve. Algorithm idea: Create an auxiliary array S of size p, temporarily store the first p integers in R in S in turn, and shift the last np integers in R to the left, and then put back the p numbers temporarily stored in S in turn to subsequent cells in R. The time complexity is O(n), and the space complexity is O(p).

6、

1) The basic design idea of ​​the algorithm is as follows:
Find the medians of two ascending sequences A and B respectively, set a and b, and find the medians of sequences A and B as follows:

If a=b, then a or b is the desired median, and the algorithm ends.
If a<b, discard the smaller half of sequence A and discard the larger half of sequence B, requiring the lengths of the two discards to be equal.
If a>b, the larger half of sequence A is discarded, and the smaller half of sequence B is discarded, and the lengths of the two discards are required to be equal.
In the two ascending sequences retained, repeat the above 123 process until the two sequences contain only one element, the smaller one is the required median.

int M_Search(int A[], int B[], int n) {
    int s1 = 0, d1 = n - 1, m1, s2 = 0, d2 = n - 1, m2;
    //分别表示序列A和B的首位数,末位数和中位数
    while (s1 != d1 || s2 || d2) {
        m1 = s1 + ((d1 - s1) >> 1);
        m2 = s2 + ((d2 - s2) >> 1);
        if (A[m1] == B[m2])
            return A[m1];   //满足条件1
        if (A[m1] < B[m2]) {//满足条件2
            if ((s1 + d1) % 2 == 0) {//若元素个数为奇数
                s1 = m1;    //舍弃A中间点以前的部分并保留中间点
                d2 = m2;    //舍弃B中间点以后的部分并保留中间点
            }else{       //若元素个数为偶数
                s1 = m1 + 1;//舍弃A中间点及中间点之前部分
                d2 = m2;    //舍弃B中间点以后部分并保留中间点
            }         
        }
        else {              //满足条件3
            if ((s2 + d2) % 2 == 0) {//若元素个数为奇数
                d1 = m1;    //舍弃A中间点以后的部分并保留中间点
                s2 = m2;    //舍弃B中间点以前的部分并保留中间点
            }
            else { //元素个数为偶数
                d1 = m1;    //舍弃A中间点以后部分并保留中间点
                s2 = m2 + 1;//舍弃B中间点及中间点以前的部分
            }
        }
    }return A[s1] < B[s2] ? A[s1] : B[s2];
}

The time complexity of the algorithm is O(log2n), and the space complexity is O(1).

7、

 

 The strategy of the algorithm is to scan the array elements from front to back, and mark an element Num that may become the main element. Then count again to confirm whether Num is element-wise.
The algorithm can be divided into the following two steps:
1. Select the candidate element-wise. Scan each integer in the given array in turn, save the first encountered integer Num in c, record the number of occurrences of Num as 1; if the next integer encountered is still equal to Num, add 1 to the count, otherwise , the count is reduced by 1; when the count is reduced to 0, the next integer encountered is saved in c, the count is re-recorded as 1, and a new round of counting is started, that is, the above process is repeated from the current position until the entire array is scanned element.
2. Determine whether the element in c is the real main element. Scan the array again, count the number of occurrences of elements in c, if it is greater than n/2, it is the main element; otherwise, there is no main element in the sequence.
实现的程序的时间复杂度为O(n),空间复杂度为O(1)。
本题如果采用先排好序再统计的方法(时间复杂度可为O(nlog2n)),只要解答正确,最高可拿11分。即便是写出O(n^2)的算法,最高也能拿10分,因此对于统考算法题,花费大量时间去思考最优解法是得不偿失的。

8、

 

Requirement: To be as efficient as possible in terms of time.

My idea is to directly compare the smallest positive integer with the element. If there is such an element, add one and continue the comparison. However, suppose you are looking for 0 3 5 4 6 2 4 5 8 98 43 1 334 554 3 4 3, start from 0, encounter 0, add one, and then 1=? When encountering 1, continue to compare backwards from this element to see if there is 2=?, but it is in front of 1. Garbage, the algorithm doesn't work.

Wang Dao Thought:

The basic design idea of ​​the algorithm:
it is required to be as efficient as possible in time, so the method of exchanging time for space is adopted. Allocate an array B[n] for marking, which is used to record whether a positive integer 1 -- n appears in A, B[0] corresponds to a positive integer 1, B[n-1] corresponds to a positive integer n, initialize All are 0 in B. Since A contains n integers, the possible returned values ​​are 1~(n+1). When a value less than or equal to 0 or greater than n appears in the array A, it will result in a vacant position in 1~n, and the returned result must be in 1~n, so for a value less than or equal to 0 or greater than n in A, you can Take no action.
After the above analysis, the algorithm flow can be obtained, starting from A[0] to traverse A, if 0<A[i]<=n, then set B[A[i]-1]=1; otherwise do not operate. After traversing A, start traversing array B. If you can find the first subscript i that satisfies B[i]==0, return i+1 as the result. At this time, it means that the smallest integer that does not appear in A is in between 1 and n. If all B[i] are not 0, return i+1 (i=n when jumping out of the loop, i+1 is equal to n+1), at this time, it means that the smallest positive integer that does not appear in A is n+1.

I don't understand.

int findMissMin(int A[], int n) {
    int i, * B;
    B = (int*)malloc(sizeof(int) * n);//分配空间
    memset(B, 0, sizeof(int) * n);  //赋初值为0
    for (i = 0; i < n; i++) {
        if (A[i] > 0 && A[i] <= n) //若A[i]的值介于1~n,则标记数组B
            B[A[i] - 1] = 1;
    }
    for (i = 0; i < n; i++)//扫描数组B,找到目标值
        if (B[i] == 0)break;
    return i + 1;//返回结果
}

时间复杂度,A遍历一次,B遍历一次,两次循环内操作步骤为O(1)量级,因此时间复杂度为O(n)。空间复杂度:额外分配了B[n],空间复杂度为O(n)。

9、

From D=|ab|+|bc|+|ca|>=0, the following conclusions can be drawn:
1. When a=b=c, the distance is the smallest.
2. In other cases, without loss of generality, assuming a<=b<=c, observe the following number axis:

 

From the expression of D, it can be known that the key to determine the size of D is the distance between a and c, so the problem can be simplified as finding an a every time c is fixed, so that L3=|ca| is the smallest.
1)算法的基本设计思想 

#define INT_MAX 0x7fffffff
int abs_(int a) {
    //计算绝对值
    if (a < 0)return -a;
    else return a;
}
bool xls_min(int a, int b, int c) {
    //a是否是三个数中的最小值
    if (a <= b && a <= c)return true;
    return false;
}
int findMinoTrip(int A[], int n, int B[], int m, int C[], int p) {
    //D_min用于记录三元组的最小距离,初值赋为INT_MAX
    int i = 0, j = 0, k = 0, D_min = INT_MAX, D;
    while (i < n && j < m && k < p && D_min>0) {
        D = abs_(A[i] - B[j]) + abs_(B[j] - C[k]) + abs_(C[k] - A[i]);//计算D
        if (D < D_min) D_min = D;//更新D
        if (xls_min(A[i], B[j], C[k]))i++;//更新a
        else if (xls_min(B[j], C[k], A[i]))j++;
        else k++;
    }return D_min;
}

 

in conclusion:

This exam can ask questions that you find inexplicable, and it is a test of the mastery and application of algorithms. Find a way to catch sensitive times, and focus on the two chapters of search and sorting. After all, the big questions must be solved here.

New skills learned this time: 1. Direct i++, no need to start a new line. 2. Traverse it from beginning to end, if it is not equal to x, put it into another array. This is a good line of thought to keep in mind. 3. Find a way to use the following algorithm directly.

Guess you like

Origin blog.csdn.net/weixin_48060069/article/details/127243489