zoukankan      html  css  js  c++  java
  • 算法第二章上机实践报告

    实践题目 7-3 两个有序序列的中位数 

    问题描述 

    已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列,的中位数指A(N1)/2​​的值,即第⌊个数(A0​​为第1个数)。

    输入格式:

    输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。

    输出格式:

    在一行中输出两个输入序列的并集序列的中位数。

    输入样例1:

    5
    1 3 5 7 9
    2 3 4 5 6
    

    输出样例1:

    4
    

    输入样例2:

    6
    -100 -10 1 1 1 1
    -50 0 2 3 4 5
    

    输出样例2:

    1




    算法描述:二分搜索,递归查找两个数组A,B的中位数,(中位数位置 =(Left + Right)/2),
    如果A数组中位数小于B数组中位数递归查找A中间到右边的中位数和数组B左边到中间的中位数,
    如果A数组中位数大于B数组中位数,则递归查找A数组左边到中间的中位数和B数组中间到左边的中位数,

    边界条件是当数组A和数组B元素个数都为2时无法再递归查找中位数时,直接判断数组A和数组B4个元素的中位数,
    判断方法为
    若A第一个元素小于B第一个元素,那么A第一个元素不可能是中位数(因为A第二个元素B第一第二个元素都比A第一个元素大,A第一个元素就一定是最小的),
    接着判断A第二元素和B第一个元素,
    若A第二个元素比B第一个元素小,那么A第二元素就为中位数(说明A第二元素大于A第一元素同时必定小于B第一个和第二个元素,该例子中4个数中第二大的为中位数),
    若A第二元素比B第一个元素大,那么B第一个元素就为中位数(说明B第一个元素小于B第二个元素和A第二个元素,同时B第一个元素又大于A第一个元素,则B第一个元素为中位数)。

    若A第一元素大于B第一个元素,接着判断推理同上类似
    边界判断代码实现:
    if (aRight - aLeft == 1 || bRight - bLeft == 1)
        {
            if (a[aLeft] < b[bLeft])
                return a[aRight] < b[bLeft] ? a[aRight] : b[bLeft];
            else
                return b[bRight] < a[aLeft] ? b[bRight] : a[aLeft];
        }

    在递归查找中位数时调试出现问题,若数组AB元素为奇数时,那么数组AB中间切分时不会出现个数不一样的情况,但若AB数组元素个数为偶数时如为4时,切分数组时会出现个数分别为2和3的情况,
    为了避免这种情况发生,就要舍掉一个元素或者多加一个元素,若A数组中位数小于B数组中位数,二分一半时A会分到 N/2+1元素(N为偶数),而B数组分到N/2个元素(N为偶数),分B数组时多加一个元素就可以让两个数组个数一致,
    让B数组分到BRight到Bmid+1就可以了;若A数组中位数大于B数组中位数,则让A数组从ALeft分到Amid+1即可。
    递归代码实现:
    if (a[medianA] == b[medianB])
                return a[medianA];
            else if (a[medianA] < b[medianB])
            {
                if ((aRight - aLeft + 1) % 2 == 1)
                    return biSearchMedian(a, medianA, aRight,
                        b, bLeft, medianB);
                else
                    return biSearchMedian(a, medianA, aRight,  // medianA + 1? - 1 ?
                        b, bLeft, medianB + 1);
            }
            else
            {
                if ((bRight - bLeft + 1) % 2 == 1)
                    return biSearchMedian(a, aLeft, medianA, 
                        b, medianB, bRight);
                else
                    return biSearchMedian(a, aLeft, medianA + 1,
                        b, medianB, bRight);
            }
        }
    完整函数实现:
    int biSearchMedian(int *a, int aLeft, int aRight, 
        int *b, int bLeft, int bRight)
    {
        int medianA = (aRight + aLeft) / 2;  // (aRight - aLeft + 2) / 2 (x) 第floor((N+1)/2)个数! (aRight - aLeft + 1) / 2(x) 如果这样算下标,第一个例子第二次在函数时madianA = medianB = 1
        int medianB = (bRight + bLeft) / 2;
    
        if (aRight - aLeft == 1 || bRight - bLeft == 1)
        {
            if (a[aLeft] < b[bLeft])
                return a[aRight] < b[bLeft] ? a[aRight] : b[bLeft];
            else
                return b[bRight] < a[aLeft] ? b[bRight] : a[aLeft];
        }
        else
        {
            if (a[medianA] == b[medianB])
                return a[medianA];
            else if (a[medianA] < b[medianB])
            {
                if ((aRight - aLeft + 1) % 2 == 1)
                    return biSearchMedian(a, medianA, aRight,
                        b, bLeft, medianB);
                else
                    return biSearchMedian(a, medianA, aRight,  // medianA + 1? - 1 ?
                        b, bLeft, medianB + 1);
            }
            else
            {
                if ((bRight - bLeft + 1) % 2 == 1)
                    return biSearchMedian(a, aLeft, medianA, 
                        b, medianB, bRight);
                else
                    return biSearchMedian(a, aLeft, medianA + 1,
                        b, medianB, bRight);
            }
        }
    }
    
    

    算法时间及空间复杂度分析

    时间复杂度为Ologn,因为用了二分搜索的方法,范围从一开始n逐步缩减到n/2, n/4... 所以是Olog2n的时间复杂度

    空间复杂度为O1,因为没有用到辅助的空间,所以空间复杂度为O1

    心得体会

    一开始用的是归并的思想,因为已经归好了直接并就行了,但是这样的时间复杂度是On,空间复杂度为On,因为题目要求时间复杂度为OlogN,就只能采取二分搜索了,二分搜索是一种比较快的算法了。

     
  • 相关阅读:
    48. Rotate Image
    83. Remove Duplicates from Sorted List
    46. Permutations
    HTML5笔记
    18. 4Sum
    24. Swap Nodes in Pairs
    42. Trapping Rain Water
    Python modf() 函数
    Python min() 函数
    Python max() 函数
  • 原文地址:https://www.cnblogs.com/likeghee/p/11545586.html
Copyright © 2011-2022 走看看