3-5-多数组k大值

题目描述:

  给定两个有序数组arr1和arr2,在给定一个整数k,返回两个数组的所有数中第K小的数。
  例如:
    arr1 = {1,2,3,4,5};
    arr2 = {3,4,5};
    K = 1;
  因为1为所有数中最小的,所以返回1;

    arr1 = {1,2,3};
    arr2 = {3,4,5,6};
    K = 4;
  因为3为所有数中第4小的数,所以返回3;

要求:如果arr1的长度为N,arr2的长度为M,时间复杂度请达到O(log(min{M,N}))。

  1 /*
  2     思路:利用上一题NowClass3-4-GetUpMedian的求上中位数的思路进行求解。
  3         arr1和arr2,其中数组长度分别为:lenS和lenL(lenS<=lenL)
  4         分情况分析:
  5             1) kth <= lenS;
  6                 只需求arr1和arr2的前kth个数的上中位数即可。
  7                 即:findProcess(arr1, 0, kth-1, arr2, 0, kth-1).
  8             2) kth > lenL;
  9                 arr1中前kth-lenL-1个数不可能是第kth个数,
 10                 arr2中前kth-lenS-1个数不可能是第kth个数,
 11                 此时,arr1中剩余(lenS-(kth-lenL-1))=lenS+lenL+1-kth个可能的数,
 12                 arr2中剩余(lenL-(kth-lenS-1))=lenL+lenS+1-kth个可能的数。剩余个数相同。
 13                 然后,先判断arr1中的第kth-lenL-1个数是否大于arr2的最后一个数,
 14                     如果是则直接返回arr1的第kth-lenL-1个数即可。
 15                     再判断arr2中的第kth-lenS-1个数是否大于arr1的最后一个数,
 16                     如果是则直接返回arr2的第kth-lenS-1个数。
 17                 否则求arr1的(kth-lenS,lenS)和arr2的(kth-lenL,lenL)的上中位数。
 18                 即:findProcess(arr1,kth-lenS,lenS,arr2,kth-lenL,lenL).
 19             3) lenS < kth <= lenL;
 20               arr1中lenS个数都有可能,
 21               arr2中(0, kth-1-lenS-1)和(kth-1,lenL-1)不可能,此时剩余kth-1-(kth-1-lenS-1)=lenS+1个数
 22                 然后,单独对地kth-lenS-1验证,是否大于arr1的最后一个数,如果是则直接返回该数;
 23                 否则,求arr1的(0,lenS-1)和arr2的(kth-lenS,kth-1)个数求上中位数。
 24                 即:findProcess(arr1,0,lenS-1,arr2, kth-lenS, kth-1).
 25 */
 26
 27 #include <iostream>
 28 #include <vector>
 29 using namespace std;
 30
 31 // 查找两个数组的上中位数。
 32 int findProcess(vector<int> arr1, int l1, int r1, vector<int> arr2, int l2, int r2){
 33     if (l1 == r1)
 34         return (arr1[l1] < arr2[l2] ? arr1[l1] : arr2[l2]);
 35     // 元素个数为奇数,则offset=0;否则offset=1.
 36     int offset = ((r1-l1+1)&1) ^ 1;
 37     int mid1 = (l1+r1)/2;
 38     int mid2 = (l2+r2)/2;
 39     if (arr1[mid1] > arr2[mid2])
 40         return findProcess(arr1, l1, mid1, arr2, mid2+offset, r2);
 41     else if(arr1[mid1] < arr2[mid2])
 42         return findProcess(arr1, mid1+offset, r1, arr2, l2, mid2);
 43     else
 44         return arr1[mid1];
 45 }
 46
 47 int findKthNum(vector<int> arr1, vector<int> arr2, int kth){
 48     if (kth <= 0 || kth > arr1.size()+arr2.size())
 49         exit(-1);
 50     vector<int> arrS = arr1.size() < arr2.size() ? arr1 : arr2;
 51     vector<int> arrL = arr1.size() < arr2.size() ? arr2 : arr1;
 52     int lenS = arrS.size();
 53     int lenL = arrL.size();
 54     if (kth <= lenS)
 55         return findProcess(arrS, 0, kth-1, arrL, 0, kth-1);
 56     else if (kth > lenL){
 57         if (arrS[kth-lenL-1] >= arrL[lenL-1])
 58             return arrS[kth-lenL-1];
 59         else if (arrL[kth-lenS-1] >= arrS[lenS-1])
 60             return arrL[kth-lenS-1];
 61         else
 62             return findProcess(arrS, kth-lenL, lenS-1, arrL, kth-lenS, lenL-1);
 63     }
 64     else{
 65         if (arrL[kth-lenS-1] >= arrS[lenS-1])
 66             return arrL[kth-lenS-1];
 67         else
 68             return findProcess(arrS,0,lenS-1,arrL, kth-lenS, kth-1);
 69     }
 70 }
 71
 72 int main(){
 73     vector<int> a1;
 74     a1.push_back(1);
 75     a1.push_back(1);
 76     a1.push_back(1);
 77     a1.push_back(2);
 78     a1.push_back(3);
 79     a1.push_back(4);
 80
 81     a1.push_back(6);
 82     a1.push_back(6);
 83     a1.push_back(6);
 84
 85     a1.push_back(8);
 86     a1.push_back(8);
 87     a1.push_back(8);
 88
 89     a1.push_back(10);
 90     a1.push_back(10);
 91     a1.push_back(10);
 92     a1.push_back(11);
 93     a1.push_back(12);
 94     a1.push_back(18);
 95     a1.push_back(19);
 96
 97     vector<int> a2;
 98     a2.push_back(11);
 99     a2.push_back(19);
100     a2.push_back(21);
101     a2.push_back(33);
102     a2.push_back(42);
103     a2.push_back(50);
104     a2.push_back(50);
105     cout << findKthNum(a1,a2,19) << endl;
106     return 0;
107 }
时间: 2024-10-17 08:46:40

3-5-多数组k大值的相关文章

POJ2985 The k-th Largest Group[树状数组求第k大值 并查集]

The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted: 2875 Description Newman likes playing with cats. He possesses lots of cats in his home. Because the number of cats is really huge, Newman wants to g

动态求区间K大值(权值线段树)

我们知道我们可以通过主席树来维护静态区间第K大值.我们又知道主席树满足可加性,所以我们可以用树状数组来维护主席树,树状数组的每一个节点都可以开一颗主席树,然后一起做. 我们注意到树状数组的每一棵树都和前一颗树没有关系,so,并不需要可持久化,一个朴素的权值线段树就可以啦. 我们知道普通的线段树是刚开始就把所有的节点都开了,但我们发现并不需要,因为每个点里的操作并不是很多,很大一部分的节点是用不到的,那么我们就可以不开.用Ls 和 Rs 来记左右儿子的地址,随用随开即可. #include<bit

HDU - 2639(01背包求第K大值)

传送门 题意:it will be a strictly decreasing sequence from the 1st maximum , 2nd maximum .. to the K-th maximum.  If the total number of different values is less than K,just ouput 0. 输入:T组数据 体积V 要求的K    N , V, K(N <= 100 , V <= 1000 , K <= 30) 各项价值 各项

背包问题--求第K大值

这算法有毒,一不小心沾上了不死也脱皮! 在背包问题中这个求第K大值就骚扰了我一整天,让我心神不宁,浑身难受- -! 我看到的这种写法是把原本的DP[X]加一维变成DP[X][Y],X用来确定当前背包容量,Y则是Y个值,分别是记录从最大到第K大,(因为只要求K大,所以那些更小的值就不用记录了) 接下来是讨论这个DP[X][Y],可以理解为它是表示的背包容量为X时的第Y大值,而DP[X][ ]可以理解为所有背包容量为X时的值,这样就方便下面的理解了. 在一般背包解决问题中用的01背包公式大约就是DP

PAT天梯赛练习题 L3-002. 堆栈(线段树查询第K大值)

L3-002. 堆栈 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 大家都知道“堆栈”是一种“先进后出”的线性结构,基本操作有“入栈”(将新元素插入栈顶)和“出栈”(将栈顶元素的值返回并从堆栈中将其删除).现请你实现一种特殊的堆栈,它多了一种操作叫“查中值”,即返回堆栈中所有元素的中值.对于N个元素,若N是偶数,则中值定义为第N/2个最小元:若N是奇数,则中值定义为第(N+1)/2个最小元. 输入格式: 输入第一行给出正整

hdu 2665 可持久化线段树求区间第K大值(函数式线段树||主席树)

http://acm.hdu.edu.cn/showproblem.php?pid=2665 Problem Description Give you a sequence and ask you the kth big number of a inteval. Input The first line is the number of the test cases. For each test case, the first line contain two integer n and m (

【poj1901-求区间第k大值(带修改)】树状数组套主席树

901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7025  Solved: 2925[Submit][Status][Discuss] Description 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]

The kth great number multiset应用(找第k大值)

The kth great number Xiao Ming and Xiao Bao are playing a simple Numbers game. In a round Xiao Ming can choose to write down a number, or ask Xiao Bao what the kth great number is. Because the number written by Xiao Ming is too much, Xiao Bao is feel

POJ 2104 区间第K大值(划分树做法)

由于深感自己水平低下,把大部分有效时间放在了刷题上,于是好久没写题解了.今天刚学了下划分树的原理,于是写道简单题练练手. 题目链接:http://poj.org/problem?id=2104 划分树的空间复杂度和时间复杂度均为O(nlogn),对于解决该问题而言,每次查询的复杂度为O(logn),比归并树O((log)^3)节省时间[归并树采用了三次二分]. 但是划分树也有自己的缺点,不支持更新以及适用范围狭窄,总之...是时代的眼泪了= = AC代码: #include <iostream>