递归

	int find_kth(vector<int>& nums1, int begin1, int size1, vector<int>& nums2, int begin2, int size2, int k)
{
size1 = min(k, size1);//第k大最多只要前k个
size2 = min(k, size2);
if (k == 1)
{
return min(nums1[begin1], nums2[begin2]);
}
if (size1 == 1)
{
if (begin2 + k - 1 < nums2.size())
return min(max(nums1[begin1], nums2[begin2 + k - 2]), nums2[begin2 + k - 1]);
else
return max(nums1[begin1], nums2[begin2 + k - 2]);
}
if (size2 == 1)
{
if (begin1 + k - 1 < nums1.size())
return min(max(nums2[begin2], nums1[begin1 + k - 2]), nums1[begin1 + k - 1]);
else
return max(nums2[begin1], nums1[begin1 + k - 2]);
}
double s = k / static_cast<double>(size1 + size2);//对应的比例位置
int q = s*(size1)+begin1;/**/
int p = s*(size2)+begin2;/**/
if (static_cast<int>(s*(size1)) + static_cast<int>(s*(size2))> k - 1 && (q - begin1) && (p - begin2))
//调节使 k刚好落在p 或 k,p k有可能是第k大在下一轮仍保留
{
--p;
--q;
}
if (static_cast<int>(s*(size1)) + static_cast<int>(s*(size2))< k - 3 && (q - begin1) && (p - begin2))
//调节使 k刚好落在p 或 k
{
++p;
++q;
}
if (nums1[q] > nums2[p])
{
k = k - (p - begin2);
size1 = q - begin1 + 1;
size2 -= (p - begin2);
begin2 = p;
}
else
{
if (nums1[q] < nums2[p])
{
k = k - (q - begin1);
size1 -= (q - begin1);
begin1 = q;
size2 = p - begin2 + 1;
}
else
{
return nums1[q];
}
}
return find_kth(nums1, begin1, size1, nums2, begin2, size2, k);
}

  迭代

int find_kth(vector<int>& nums1, int begin1, int size1, vector<int>& nums2, int begin2, int size2, int k)
{
while (!(size2 == 1 || size1 == 1 || k == 1))
{
size1 = min(k, size1);//第k大最多只要前k个
size2 = min(k, size2);
double s = k / static_cast<double>(size1 + size2);//对应的比例位置
int q = s*(size1)+begin1;/**/
int p = s*(size2)+begin2;/**/
if (static_cast<int>(s*(size1)) + static_cast<int>(s*(size2)) > k - 1 && (q - begin1) && (p - begin2))
//调节使 k刚好落在p 或 k
{
--p;
--q;
}
if (static_cast<int>(s*(size1)) + static_cast<int>(s*(size2)) < k - 3 && (q - begin1) && (p - begin2))
//调节使 k刚好落在p 或 k p k可能为第k大下轮保留
{
++p;
++q;
}
if (nums1[q] > nums2[p])
{
k = k - (p - begin2);
size1 = q - begin1 + 1;
size2 -= (p - begin2);
begin2 = p;
}
else
{
if (nums1[q] < nums2[p])
{
k = k - (q - begin1);
size1 -= (q - begin1);
begin1 = q;
size2 = p - begin2 + 1;
}
else
{
return nums1[q];
}
}
}
if (k == 1)
{
return min(nums1[begin1], nums2[begin2]);
}
if (size1 == 1)
{
if (begin2 + k - 1 < nums2.size())
return min(max(nums1[begin1], nums2[begin2 + k - 2]), nums2[begin2 + k - 1]);
else
return max(nums1[begin1], nums2[begin2 + k - 2]);
}
if (size2 == 1)
{
if (begin1 + k - 1 < nums1.size())
return min(max(nums2[begin2], nums1[begin1 + k - 2]), nums1[begin1 + k - 1]);
else
return max(nums2[begin1], nums1[begin1 + k - 2]);
}
}

  

log(m+n)找第k大的更多相关文章

  1. 找第k大的数

    (找第k大的数) 给定一个长度为1,000,000的无序正整数序列,以及另一个数n(1<=n<=1000000),接下来以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{ ...

  2. 快速排序算法的实现 && 随机生成区间里的数 && O(n)找第k小 && O(nlogk)找前k大

    思路:固定一个数,把这个数放到合法的位置,然后左边的数都是比它小,右边的数都是比它大 固定权值选的是第一个数,或者一个随机数 因为固定的是左端点,所以一开始需要在右端点开始,找一个小于权值的数,从左端 ...

  3. luogu_P1177 【模板】快速排序 (快排和找第k大的数)

    [算法] 选取pivot,然后每趟快排用双指针扫描(l,r)区间,交换左指针大于pivot的元素和右指针小于pivot的元素,将区间分成大于pivot和小于pivot的 [注意] 时间复杂度取决于pi ...

  4. 从一组数找第K大元素

    最近做面试题,经常与到一个问题,如何高效的从一组数中找到第K大的元素. 其实我们最容易想到的肯定是蛮力法. 1. 我们可以对这个乱序数组按照从大到小先行排序,然后取出前k大,总的时间复杂度为O(n*l ...

  5. O(n)线性时间找第K大,中位数

    运用快速排序的思想,可以达到线性时间找到一串数的第K大 #include<cstdio> #define F(i,a,b) for(int i=a;i<=b;i++) ],n; vo ...

  6. CSUOJ2078-查找第k大(读入挂)

    查找第k大 Submit Page Output 对于每组数据,输出第k大的数 Sample Input 1 6 2 1 2 3 4 5 6 Sample Output 5 Hint #include ...

  7. P1049 找第K大的数

    题目描述 给定一个无序正整数序列, 以及另一个数n (1<=n<=1000000), 然后以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{1,2,3,4,5,6}中第3 ...

  8. HDU - 4006 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 ...

  9. 快排找第k大模板

    int get_kth(int l,int r) { if (l==r) return a[r]; ]; while (i<j) { while (a[i]<mid) i++; while ...

随机推荐

  1. ELK 日志管理系统,初次尝试记录

    简介: ELK 是一套开源的日志管理平台,主要包括三个组件,可以用于日志的收集.分析.存储和展示工作. ELK 成员:Elasticsearch .Logstash .Kibana( K4 ) ELK ...

  2. iPhone开发随想:rand()还是arc4random()

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://bj007.blog.51cto.com/1701577/544006 今天在iP ...

  3. bootstrap-select.js 下拉框多选后动态赋值

    话不多说先上demo 其实demo是从官网下载的 只稍作改动 由于没有搞清楚怎么上传源代码 就把官网的链接贴出来吧 https://github.com/silviomoreto/bootstrap- ...

  4. Android 定时重复启动弹出窗口。

    本来想着用handlerpostdelay就可以实现,没想到演示后关闭应用居然报错. 后来想到是没有了activity. ((Activity)context).isFinishing() 可以传入c ...

  5. Setup Apache2 in Debian 9 and enable two ports for two sites

    root@debian:~# apt-get install apache2 root@debian:~# cd /etc/apache2/ root@debian:/etc/apache2# ls ...

  6. 3D数学基础 KeyNote 1

    [计算几何复习要点] 1.向量加法的几何含意: a+b的释意为:a的尾连上b的头,新建一条从a的尾指向b的头的向量. 2.向量减法的几何含意: a-b的释意为:尾部相连,新建一个从b的头指向a的头的向 ...

  7. 平衡二叉树之RB树

    RB树(红黑树)并不追求“完全平衡”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能.由于它的设计,任何不平衡都会在三次旋转之内解决.典型的用途是实现关联数组(如C++中的map和s ...

  8. 344. Reverse String 最基础的反转字符串

    [抄题]: [暴力解法]: 时间分析: 空间分析: [奇葩输出条件]: [奇葩corner case]: [思维问题]: 还停留在 i < len / 2的阶段,不行,应该是指针对撞问题了 [一 ...

  9. Spring中通配符(转)

    一.加载路径中的通配符:?(匹配单个字符),*(匹配除/外任意字符).**/(匹配任意多个目录) classpath:app-Beans.xml 说明:无通配符,必须完全匹配   classpath: ...

  10. loadrunner怎么进行内容检查

    运行测试时,常常需要验证某些内容是否出现在返回的页面上.内容检查验证脚本运行时 Web 页面上是否出现期望的信息.可以插入两种类型的内容检查:➤ 文本检查.检查文本字符串是否出现在 Web 页面上.➤ ...