leetcode | Median of Two Sorted Arrays 寻找2个有序数组中第k大的值

问题 Median of Two Sorted Arrays

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays.
The overall run time complexity should be O(log(m + n)).

分析

本题更经典通用的描述方式时:

给定2个有序数组,找出2个数组中所有元素中第k大的元素。

思路1

直观思路就是类似merge-sort,将2个数组merge成一个数组,即可得到第k大的值,但是时间复杂度O(m+n);

思路2

然后我们仅需要第k大的元素,不需要排序这个复杂的操作:可以定义一个计数器m,表示找到了第m大的元素;同时指针pa,pb分别指向数组A,B的第一个元素,使用merge-sort的方式,当A的当前元素小于B的当前元素时:pa++, m++,当*pb < *pa时,pb++, m++。最终当m等于k时,就得到了第k大的元素。时间复杂度O(k),但是当k接近于m+n时,复杂度还是O(m+n);

思路3

从题目中的要求O(log(m+n))可以联想到肯定要用到二分查找的思想

那么有没有更好的方案?我们可以考虑从k入手。如果我们每次能够删除一个一定处于第k大元素之前的元素,那么需要进行k次。但是如果我们每次都能删除一半呢?可以利用A,B有序的信息,类似二分查找,也是充分利用有序。

假设A 和B 的元素个数都大于k/2,我们将A 的第k/2 个元素(即A[k/2-1])和B 的第k/2个元素(即B[k/2-1])进行比较,有以下三种情况(为了简化这里先假设k 为偶数,所得到的结论对于k 是奇数也是成立的):

- A[k/2 - 1] == B[k/2 - 1];

- A[k/2 - 1] > B[k/2 - 1];

- A[k/2 - 1] < B[k/2 - 1];

如果A[k/2 - 1] < B[k/2 - 1] ,意味着 A[0] 到 A[k/2 - 1] 的元素一定小于 A+B 第k大的元素。因此可以放心的删除A数组中的这k/2个元素;

同理,A[k/2 - 1] > B[k/2 - 1];可以删除B数组中的k/2个元素;

当A[k/2 - 1] == B[k/2 - 1] 时,说明找到了第k大的元素,直接返回A[k/2 - 1] 或B[k/2 - 1]的值。

因此可以写一个递归实现,递归终止条件是什么呢?

- A或B为空时,直接返回A[k-1] 或 B[k-1]

- 当k = 1时,返回min(A[0], B[0]) //第1小表示第一个元素

- 当A[k/2 - 1] == B[k/2 - 1] 时,返回A[k/2 - 1] 或B[k/2 - 1]

C语言实现

    static int find_kth(int* A, int m,int* B, int n, int k);
    static int min(p, q) {return (p < q) ? p : q;}
    double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
        int m = nums1Size;
        int n = nums2Size;
        int total = m+n;
        int k = total/2;
        if(total & 0x01) {
            return find_kth(nums1, m, nums2, n, k+1); //奇数,返回唯一中间值
        } else {
            return (find_kth(nums1, m, nums2, n, k) + find_kth(nums1, m, nums2, n, k+1)) / 2.0; //偶数,返回中间2个的平均值
        }
    }
    //找到A,B组合中第k小的值: AB[k-1]
    int find_kth(int* A, int m,int* B, int n, int k) {
        //假设m都小于n
        if (m > n)
            return find_kth(B, n, A, m, k);
        if (m == 0)
            return B[k-1];
        if (k == 1) //终止条件
            return min(A[0], B[0]);

        int i_a = min(m, k/2);
        int i_b = k - i_a;

        if (A[i_a-1] < B[i_b-1])
            return find_kth(A+i_a, m-i_a, B, n, k-i_a);
        else if (A[i_a-1] > B[i_b-1])
            return find_kth(A, m, B+i_b, n-i_b, k-i_b);
        else
            return A[i_a-1];
    }

参考:https://github.com/soulmachine/leetcode

时间: 2024-08-02 07:03:19

leetcode | Median of Two Sorted Arrays 寻找2个有序数组中第k大的值的相关文章

LeetCode——Median of Two Sorted Arrays

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 有两个已排序的数组A和B,大小为m 和 n. 找出两数组的中位数 时间复杂度应该为 O(log (m+n)). 简单粗暴的方法就是把两个数组合并成一个数组,排序,取中位数.

[leetcode]Median of Two Sorted Arrays @ Python

原题地址:https://oj.leetcode.com/problems/median-of-two-sorted-arrays/ 题意:There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 解题思路:这道题要求两个已经排好

[LeetCode] Median of Two Sorted Arrays [16]

题目 There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 原题链接(点我) 解题思路 返回两个排序数组的中位数.这个题可以有以下几个思路: 首先可以想到的是将两个数组merge起来,然后返回其中位数. 第二个是,类似merg

[LeetCode] Kth Largest Element in an Array 数组中第k大的数字

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. For example, Given [3,2,1,5,6,4] and k = 2, return 5. Note: You may assume k is always valid, 1 ≤ k ≤ array'

[经典算法题]寻找数组中第K大的数的方法总结

[经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26 字体:[大 中 小] 打印复制链接我要评论 今天看算法分析是,看到一个这样的问题,就是在一堆数据中查找到第k个大的值. 名称是:设计一组N个数,确定其中第k个最大值,这是一个选择问题,当然,解决这个问题的方法很多,本人在网上搜索了一番,查找到以下的方式,决定很好,推荐给大家. 所谓"第(前)k大数问题"指的是在长度为n(n>=k)的乱序数组中S找出从大到小顺序的第(前)k个数的问题.

[LeetCode] Median of Two Sorted Arrays 解题报告

There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). Subscribe to see which companies asked this question Show Tags 分析: 这个题目在leetco

LeetCode—Median of Two Sorted Arrays

Median of Two Sorted Arrays 这道题要找Median,中位数.这个是指,如果数组大小是偶数,返回中间两个数的平均值,如果是奇数个,就是中间的数. 算法时间效率要求是 O(log(m + n)),具体思路网上都一样. 另外,现在leetCode的C++ 数组都换成vector了,所以只好整理一下vector的用法. 参考:http://imatlab.lofter.com/post/286ffc_a81276 http://www.cnblogs.com/wang7/ar

[JS做LeetCode] Median of Two Sorted Arrays

Median of Two Sorted Arrays <html> <head> <meta http-equiv="charset" content="utf-8"></head> <body> <script> //解题思路: //找出中位数要循环的次数为loop //posA为数组A的下标,posB为数组B的下标 //每次循环找出两个数组对应下标比较小的值,进栈,下标+1 //注意判断数

LeetCode 26 Remove Duplicates from Sorted Array (移除有序数组中重复数字)

题目链接: https://leetcode.com/problems/remove-duplicates-from-sorted-array/?tab=Description 从有序数组中移除重复数字,并且返回不重复数字的个数 遍历操作: 可以使用新的for循环 for (int n : nums){} 每次进行对比,并且更新第一个遇到不相等的元素的下标为i 对数组进行重新赋值操作 当数组长度大于1时,ans初值为1,当数组长度为0时,返回0 参考代码 : package leetcode_5