当前位置: 首页 > news >正文

[nowCoder] 两个不等长数组求第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}))。

 

这题目的难度在于时间复杂度请达到O(log(min{M,N})),参考http://www.cnblogs.com/diegodu/p/3790860.html可以达到O(log(M+N))

 

借助http://www.cnblogs.com/diegodu/p/4589847.html 求等长数组求中位数的方法能够实现。

 

举例,

arr1  1 ~ 10,

arr2  1‘ ~ 20’.

当kth = 7时,kth < min(s1,s2),  

  求两个数组的前K个元素的中位数即可,因为,第K个必然在两个数组的前K个元素中。

  getUpMedian(arr1, 0, kth - 1, arr2, 0, kth - 1);

当kth = 26时,kth>max(s1,s2)

  arr1 的1到5 是不可能的,就算5>20,也不过第25而已,不会是26.

   arr2的 1’到15‘ 是不可能的,就算15’>10,也不过第25而已,不会是26.

  所以排除了5+15个元素,arr1剩下5个,arr2剩下5个。

  如果求剩下10个元素的上中位数,我们能得到第25大的,不是第26大,

     所以,我们可以单独检验一下arr1 的6 和arr2的16‘是不是答案,

     若是直接返回,不是的话又排除了两个,排除了22个,剩余8个,求上中位数第四个,加一起正好是第26个。

当kth = 16时,min(s1, s2)<kth<max(s1,s2)

     arr1 无法排除,都有可能。

     arr2的 1’~5‘排除,就算5’大于arr1的10,也不过是15。

     arr2的 17‘~20’排除,17‘本来就排17了,最小也就是拍17。

    所以arr2还剩下 6’ ~ 16‘ 11个元素,而arr1 有10个元素,

    为了使用上中位数的算法,可以单独检测一下6’,若是返回,若不是淘汰,剩余的使用上中位数的算法。

 

http://www.nowcoder.com/profile/864393/test/231563/24588

 

class Solution {
    public:
        int getUpMedian(vector<int> arr1, vector<int> arr2) {
 
        if(arr1.size() != arr2.size())
            return -1;
        if(arr1.size() == 0)
            return -1;
 
        return getUpMedian(arr1, 0, arr1.size() -1,
                arr2, 0, arr1.size() -1 );
        }
 
        int getUpMedian(const vector<int> & arr1, int start1, int end1,
                const vector<int> & arr2, int start2, int end2)
        {
            //cout << "start1\t" << start1 << endl;
            //cout << "end1\t" << end1 << endl;
            //cout << "start2\t" << start2 << endl;
            //cout << "end2\t" << end2 << endl;
 
            if(start1 == end1)
            {
                return min(arr1[start1], arr2[start2]);
            }
 
            int size = end1 - start1 + 1;
            int halfSize;
            if(size & 0x1 == 0x1)
            {
                halfSize = (size + 1)/2;
            }
            else
            {
                halfSize = size/2;
            }
 
            if(arr1[start1 + halfSize - 1] == arr2[start2 + halfSize - 1])
                return arr1[start1 + halfSize - 1];
            else if(arr1[start1 + halfSize - 1] > arr2[start2 + halfSize - 1])
                return getUpMedian(arr1, start1, start1 + halfSize - 1,
                                    arr2, end2-(halfSize-1), end2);
            else //if(arr1[start1 + halfSize - 1] > arr2[start2 + halfSize - 1])
                return getUpMedian(arr1, end1-(halfSize-1) , end1,
                                    arr2, start2, start2 + halfSize -1);
        }
 
        int findKthNum(vector<int> arr1, vector<int> arr2, int kth)
        {
            int size1 = arr1.size();
            int size2 = arr2.size();
 
            if(size1 > size2)
                return findKthNum(arr2, arr1, kth);//ensure size1 < size2
 
            if(kth <= size1)
                return getUpMedian(arr1, 0, kth - 1, arr2, 0, kth - 1);
           else if (kth <= size2 && kth > size1)
           //i.e.s1 = 10, s2 = 20, kth = 14;
           // for arr2, kth + 1 ~ size2(15 ~ 20) is impossibly answer
           // for arr2, 1 ~ kth - size1 -1 (1 ~ 3) is impossibly answer
           // so arr2 has  20 - 6 - 3  = 11 numbers, but arr1 has 10 numbers
           // so jundge one element of arr2 firstly, the call getUpMedian
           {
                if(arr2[kth - size1 - 1] >= arr1[size1 - 1] )
                    return arr2[kth - size1 - 1];
                return getUpMedian(arr1, 0, size1-1, arr2, kth-size1, kth-1);
           }
 
           else //if (kth > size2)
           //i.e.s1 = 10, s2 = 20, kth = 25;
           // first 4(kth - s2 - 1) of arr1 is impossibly answer. so just remove them
           // first 14(kth - s1 - 1) of arr2 is impossibly answer.so just remvoe them
           // arr1 still has s1 - (kth - s2 - 1) = s1 + s2 - kth + 1 numbers (6)
           // arr2 still has s2 - (kth - s1 - 1) = s1 + s2 - kth + 1 numbers (6)
           // we removes 2 * kth - s1 - s2 -2 numbers, (18)
           // now we junge if arr1[kth-s2-1] and arr2[kth-s1-1] is the answer,if not, we remother them
           // then we removes 2 * kth - s1 - s2  numbers (20)
           // and arr1 and arr2 both have s1 + s2 - kth numbers(5)
           // we just calc upMedia of them and got the answer, 20 + 5 = 25
           {
                if(arr2[kth-size1-1] >= arr1[size1-1])
                    return arr2[kth-size1-1];
                if(arr1[kth-size2-1] >= arr2[size2-1])
                    return arr1[kth-size2-1];
               return getUpMedian(arr1, kth-size2, size1-1, arr2, kth-size1, size2-1);
           }
 
 
 
        }
};

 

相关文章:

  • Flex Cairngorm详解
  • 宽带接入
  • MongoDBTool - 测试版【GUI美化完毕】 源代码发布 --MongoDB爱好者,Winform爱好者 请进...
  • .net 流——流的类型体系简单介绍
  • 把Javascript放置到何处
  • live555学习笔记6-建立RTP会话
  • 谈谈Ext JS的组件——组件基类:Ext.Component
  • 玩转VIM编辑器-导航移动
  • [翻译]利用C#获取终端服务(Terminal Services)会话的闲置时间
  • 让Windwos Server 2008 R2 SP1的FTP真正能访问
  • 20天android学习
  • 库函数实现之字符串拷贝
  • Xqk.Data数据框架使用说明之:如何自定义数据表名
  • 优化SqlServer--数据压缩
  • devexpress chart 柱形图
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • co.js - 让异步代码同步化
  • exif信息对照
  • express如何解决request entity too large问题
  • go append函数以及写入
  • jquery ajax学习笔记
  • Markdown 语法简单说明
  • Python 反序列化安全问题(二)
  • REST架构的思考
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 机器学习中为什么要做归一化normalization
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 使用API自动生成工具优化前端工作流
  • 探索 JS 中的模块化
  • 通过几道题目学习二叉搜索树
  • kubernetes资源对象--ingress
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (五)c52学习之旅-静态数码管
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • .gitignore文件_Git:.gitignore
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .net FrameWork简介,数组,枚举
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .NET/C# 使用反射注册事件
  • .Net多线程总结
  • .net流程开发平台的一些难点(1)
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • /run/containerd/containerd.sock connect: connection refused
  • :中兴通讯为何成功
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • @html.ActionLink的几种参数格式
  • [ IOS ] iOS-控制器View的创建和生命周期