分治法求2n个数的中位数
问题:设X[0:n-1]和Y[0:n-1]为两个数组,每个数组中含有n个已排好序的数。试设计一个O(logn)时间的分治算法,找出X和Y的2n个数的中位数
思想:
对于数组X[0:n-1]和Y[0:n-1]先分别找出X和Y的中位数xa和yb。求中位数的算法是这样的,若n是奇数,即数组X和Y中各有奇数个数字,因为X和Y已经排好序了,所以去数组下标为(n-1)/2处的数即为中位数。若n是偶数,则取(n-1)/2向下取整和向上取整这两个位置的数的平均值作为中位数。
两者进行比较,
(1)若xa=yb则xa或者xb即为整个2n个数中的中位数,算法结束。因为:若每个数组中数字的个数是偶数个,则X中小于中位数的有n/2个,大于中位数的有n/2个,同理Y也是如此,所以在整个2n数组中比xa=yb小的共有n个数,比n大的共有n个数,即为中位数。若每个数组中数字的个数是奇数,则X中小于xa的有(n-1)/2个,大于xa的也有(n-1)/2个,同理Y中也是如此,所以对于xa或者是yb则整个2n数组中小于和大于他们的数分别为(n-1)个,取这两个数的平均值(xa+yb)/2=xa=yb即为中位数.
(2) 若xa>yb,则说明整个2n个数的的中位数一定在X数组的前一半和Y数组的后一半中,因为:若中位数在X数组的中位数之后,则比它小的数共有X数组中大于n/2个数以及Y数组中大于n/2个数总计超过了n个数,不符合中位数的定义。若中位数是在Y数组的前一半之中,则比它大的数字共有Y中包括中位数在内的后半部数加上X数组包括中位数在内的后半部,这样也超过了n个数,不符合中位数的定义。
(3) 若xa<yb,则同上理由,整个2n的数的中位数应该在X数组的后一半和Y数组的前一半中。
确定中位数所在的数组范围后,递归调用求中位数算法对这个范围的数组求中位数重复上述过程,直至:
1.出现xa=yb情况,找到了中位数算法结束。
2.数组分割至左右两部数组只有一个数字的情况,求其平均值即为中位数
代码:
/*
思路:求两有序数组x和y的第k个数,思路如下:
若k为1,则返回两数组的最小值
取x的第i个数x0,取y的第(k-i)个数y0
若x0=y0,则x0即为所求
若x0<y0,则丢弃x的前i个数,k=k-i,递归
若x0>y0,则丢弃y的前(k-i)个数,k=i,递归
*/
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList; public class Solution{ public int findOneSideMedian(int a[]){
int mid;
int length=a.length;
//if(a[])数组长度a.length
if((length&0x01)==0){//判断子数组的长度是奇数还是偶数
mid=(a[length/2]+a[length/2-1])/2;
}else{
mid=a[length/2];
}
return mid;
} public double findMedian(int x[],int y[] int n){
if(n==0){
break;
}
int mid_x=findOneSideMedian(x);
int mid_y=findOneSideMedian(y);
if(n==1){
return (mid_x+mid_y)/2;
}
if(mid_x==mid_y){
return mid_x;
}else if(mid_x>mid_y){
int[] x2=Arrays.copyOfRange(x,0,n/2);
int[] y2=Arrays.copyOfRange(y,Math.ceil(n/2),n);
n=n/2;
findMedian(x2,y2,n);
}else if(mid_x<mid_y){
int[] x2=Arrays.copyOfRange(x,Math.ceil(n/2),n);
int[] y2=Arrays.copyOfRange(y,0,n/2);
n=n/2;
findMedian(x2,y2,n);
}
}
}
分治法求2n个数的中位数的更多相关文章
- 分治法求一个N个元素数组的逆序数
背景 逆序数:也就是说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时, ...
- 《github一天一道算法题》:分治法求数组最大连续子序列和
看书.思考.写代码. /*************************************** * copyright@hustyangju * blog: http://blog.csdn. ...
- 算法笔记_065:分治法求逆序对(Java)
目录 1 问题描述 2 解决方案 2.1 蛮力法 2.2 分治法(归并排序) 1 问题描述 给定一个随机数数组,求取这个数组中的逆序对总个数.要求时间效率尽可能高. 那么,何为逆序对? 引用自百度 ...
- 使用分治法求X的N次方,时间效率为lgN
最近在看MIT的算法公开课,讲到分治法的求X的N次方时,只提供了数学思想,于是自己把代码写了下,虽然很简单,还是想动手写一写. int powerN(int x,int n){ if(n==0){ r ...
- hdu 1007 Quoit Design(分治法求最近点对)
大致题意:给N个点,求最近点对的距离 d :输出:r = d/2. // Time 2093 ms; Memory 1812 K #include<iostream> #include&l ...
- 分治法求解最近对问题(c++)
#include"stdafx.h" #include<iostream> #include<cmath> #define TRUE 1 #define F ...
- Leetcode之分治法专题-169. 求众数(Majority Element)
Leetcode之分治法专题-169. 求众数(Majority Element) 给定一个大小为 n 的数组,找到其中的众数.众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是 ...
- 分治法(一)(zt)
这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它 ...
- (逆序对 分治法)P1908 逆序对 洛谷
题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定 ...
随机推荐
- MVC+EF 自定义唯一性验证
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 本篇提供二种方法,希望大家喜欢 1.自定义验证属性 ...
- java字符串相关
String类默认对equals方法进行了重写,比较的是字符串的字符,而非是object中equals方法默认的比较两个对象的内存地址
- (一) ARM 内存SDRAM 讲解
2.SDRAM内存工作原理 上面产生的误解关于 Bank ,这个bank 不是 和 S3C2440 芯片有关系(RAM 自身有bank , SDRAM 自身也有bank ,就像书 有 好几章节一样) ...
- Gym 100500B
题目给了四个轮子,每个轮子上有按顺序排列的n个数,要求适当旋转每个轮子,使得四个轮子相同行数相加和相同. 首先,可以计算出每一行的和应该是多少,记为Sum.然后固定第一个轮子,二重循环枚举2.3轮子, ...
- 关于silverlight打印模糊的问题
今天做silverlight打印实现时,发现一个问题,就是sl打印处理的文字很模糊 这样肯定不行撒,于是开始找解决办法,首先想到的是silverlight中文显示的问题,好 ...
- 32、mybatis
第一章回顾jdbc开发 1)优点:简单易学,上手快,非常灵活构建SQL,效率高 2)缺点:代码繁琐,难以写出高质量的代码(例如:资源的释放,SQL注入安全性等) 开发者既要写业务逻辑,又要写对象的创建 ...
- 《Java并发编程实战》读书笔记
Subsections 线程安全(Thread safety)锁(lock)共享对象对象组合基础构建模块任务执行取消和关闭线程池的使用性能与可伸缩性并发程序的测试显示锁原子变量和非阻塞同步机制 一.线 ...
- python学习之安装模块
安装pip下载python模块 yum -y install python-pip pip install pandas (pandas要安装的模块名) 默认使用的官方python源,这个在国内访问很 ...
- python 学习笔记十三 JQuery(进阶篇)
jQuery 是一个 JavaScript 库. jQuery 极大地简化了 JavaScript 编程. 安装jQuery 有两个版本的 jQuery 可供下载: Production versio ...
- 数据库事务的特性(ACID)
数据库的事务是数据库中一系列(增删查改)操作的集合. 一般来说,事务的范围根据业务而定,比如转账.修改个人信息 转账:从A账户将200元转移到B账户 从A账户中扣除200元 将200元加入到B账户中 ...