博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
求第K大的问题
阅读量:5258 次
发布时间:2019-06-14

本文共 1169 字,大约阅读时间需要 3 分钟。

问题:现在有两个有序数组A和B,求这两个数组合并之后的第K大的元素。

方法一、使用两个指针的方式,归并排序当中合并两个数组的方式,这里不需要排序,只需要找到合并之后的第K个数即可,所以需要两个指针。时间复杂度为$O(K)$

方法二、使用折半搜索的方式将复杂度将为$O(log(K))$

算法的大体思想是:

假设要找第K个,那么我们考虑A中的前$\frac{K}{2}$个元素和B中的前$\frac{K}{2}$个元素。如果A[K/2]小于B[K/2]则将A的前K/2个元素去掉;反之,去掉B的前K/2个元素。然后在后面搜索第K/2小的元素。下一次迭代按照相同的思路来进行。知道直接确定要搜索的元素,例如其中一个数组大小为空,则直接在另外一个数组中搜索第K小。如果K为1,则直接返回A[0] B[0]中的最小者。

实际上,我们仔细想想,为什么要删除前K/2,这样一定对吗?我们可以举一个例子。

A: 1 3 6   9      11 12 35

B: 2 4 14 15    17 28 30

A+B:1 2 3 4 6 9 11 12     14 15 17

第K大为12,我们发小扔掉 13 6 9是安全的,为什么?我们只需要保证他们完全是在前K小里面即可。因为当他们是在前K小里面时,在我们丢掉他们之后再在剩下的元素当中找第K/2小,是不影响的。例如上面

1 2 3 4 6 9 11 12,丢掉 1 3 6 9

变为2 4 11 12, 在剩下的元素当中第4小就是原来的第8小。为什么会是这样?简单反正即可。

假设被删掉的元素当中有比第K小大的元素,假设为X,则在X之前至少有K个元素,但是我们知道咋被删除的数组当中比X小的不超过K/2-1个,在B中更不会有K/2-2个,所以两者相加,不可能达到K个,所以原假设不成立。从而他们一定是在前K小里面。

private int findkth(int []nums1, int start1, int s1, int [] nums2, int start2, int s2, int k){        if(s1>s2) return findkth(nums2,start2,s2,nums1,start1,s1,k);        if(s1==0) return nums2[start2+k-1];        if(k==1) return Math.min(nums1[start1],nums2[start2]);        int pa=Math.min(s1,k/2);        int pb=k-pa;        if(nums1[start1+pa-1]

 

转载于:https://www.cnblogs.com/deepblueme/p/4577083.html

你可能感兴趣的文章
ios判断app是否有打开相机的权限
查看>>
Centos7LDAP LDAPadmin的完整部署记录(改良版,其它文档太多坑)
查看>>
B. Trees in a Row(cf)
查看>>
PowerShell导出场中的WSP包到本地
查看>>
nodejs下载图片到本地,根据百度图片查找相应的图片,通过nodejs保存到本地文件夹...
查看>>
使用Jquery解析Json基础知识
查看>>
SQLserver锁和事务隔离级别的比较与使用(转)
查看>>
Problem B: 分数类的类型转换
查看>>
python-zmail发送邮件
查看>>
[转]formValidator的一些验证实例
查看>>
实验九 存储函数和触发器
查看>>
非递归遍历二叉树
查看>>
单点登录学习(2)CAS服务器端配置编程
查看>>
启动tomcat错误“Unable to load configuration”解决
查看>>
BZOJ 1012--[JSOI2008]最大数maxnumber(二分&单调栈)
查看>>
HDU 3068:最长回文(Manacher算法)
查看>>
ckeditor小记
查看>>
C#常用集合的使用(转载)
查看>>
Form Effect - 表单美化插件
查看>>
linux中test的意义 又可以表示为[]
查看>>