• 求两个有序序列合并成新有序序列的中位数,求第k小数


    此算法涉及一个重要数学结论:如果A[k/2-1]<B[k/2-1],那么A[0]~A[k/2-1]一定在第k小的数的序列当中,可以用反证法证明。

    算法思想如下:

    1,假设A长度为m,B长度为n,m>n,反之亦然。

    2,拆分k=pa+pb。

    3,如果A[pa-1]<b[pb-1],那证明第A[0]~A[pa-1]一定在合并后k小数序列中。所以,可以把A的前面pa个数字截掉,递归,同理砍掉B数组。

    4,递归的边界条件是if m=0,返回B[k-1],如果k = 1(找第一个数)就返回min[A[1],B[1])。

    C++代码

    double findKth(int a[], int m, int b[], int n, int k)
    {
        //always assume that m is equal or smaller than n
        if (m > n)
            return findKth(b, n, a, m, k);
        if (m == 0)
            return b[k - 1];
        if (k == 1)
            return min(a[0], b[0]);
        //divide k into two parts
        int pa = min(k / 2, m), pb = k - pa;
        if (a[pa - 1] < b[pb - 1])
            return findKth(a + pa, m - pa, b, n, k - pa);
        else if (a[pa - 1] > b[pb - 1])
            return findKth(a, m, b + pb, n - pb, k - pb);
        else
            return a[pa - 1];
    }
    
    class Solution
    {
    public:
        double findMedianSortedArrays(int A[], int m, int B[], int n)
        {
            int total = m + n;
            if (total & 0x1)
                return findKth(A, m, B, n, total / 2 + 1);
            else
                return (findKth(A, m, B, n, total / 2)
                        + findKth(A, m, B, n, total / 2 + 1)) / 2;
        }
    };

    Java代码

    import java.util.Arrays;
    
    
    public class FindMedianNumber {
            public double findKth(int[] nums1, int[] nums2, int k)
            {
                int m = nums1.length;
                int n = nums2.length;
                if(m > n)
                {
                    return findKth(nums2, nums1, k);
                }
                if(m==0)
                {
                    return nums2[k-1];
                }
                if(k==1)
                {
                    return Math.min(nums1[0], nums2[0]);
                }
                //拆分k
                int pa = Math.min(m, k/2), pb = k - pa;
                if(nums1[pa-1]<nums2[pb-1])
                {
                    int[] nums = Arrays.copyOfRange(nums1, pa, m);//pa小于m
                    return findKth(nums,nums2,k-pa);
                }
                else if(nums1[pa-1] > nums2[pb-1])
                {
                    int[] nums = Arrays.copyOfRange(nums2, pb, n);
                    return findKth(nums1, nums, k-pb);
                }
                else
                    return nums1[pa-1];
            }
            public double findMedianSortedArrays(int[] nums1, int[] nums2) {
                int total = nums1.length+nums2.length;
                int k = total/2;
                if(total%2==1)
                    return findKth(nums1, nums2, k+1);//注意是第k+1个数
                else
                    return (findKth(nums1, nums2, k)+findKth(nums1, nums2, k+1))/2;
            }
            
            public static void main(String[] args)
            {
                int[] nums1 = {1};
                int[] nums2 = {2,3};
                FindMedianNumber fn = new FindMedianNumber();
                System.out.println(fn.findMedianSortedArrays(nums1, nums2));
            }
    }
  • 相关阅读:
    解惑如何保证数组元素的可见性(yet)
    为什么内存锁在有事务切面的情况下会形同虚设 隔离级别与事务
    小事故合集
    第4种打整包插件,urlfactory already set
    三目运算符与字节码阅读
    servlet application/x-www-form-urlencoded 坑
    多实例重复发邮件
    当动态代理遇到ioc (五)使用cglib切面与自定义类加载器构建独有环境aop日志
    mac笔记本如何重制secureCRT的体验期|试用版本
    npm install出现的错误
  • 原文地址:https://www.cnblogs.com/masterlibin/p/5514730.html
Copyright © 2020-2023  润新知