4. Median of Two Sorted Arrays(Array; Divide-and-Conquer)
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
中位数:如果总数是偶数,那么中位数=中间两个数的平均数;如果总数是奇数,那么中位数=中间那个数的值
思路: O(logx)的算法,就想到二分法。二分法结束的条件是任何一个array只剩下一个元素了。每次递归(二分),去除某个array的一半。另外注意,每次二分至少要去掉一个元素。
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int size1 = nums1.size();
int size2 = nums2.size();
int size = size1 + size2;
int m = size >> ;
if(nums1.empty()){
if(size% == ) return nums2[m];
else return (double) (nums2[m-] + nums2[m])/;
}
if(nums2.empty()){
if(size% == ) return nums1[m];
else return (double) (nums1[m-] + nums1[m])/;
}
if(size% == ) return findK(nums1, nums2, , size1-, , size2-, m);
else return (double)(findK(nums1, nums2, , size1-, , size2-, m-)+findK(nums1, nums2, , size1-, , size2-, m))/;
}
int findK(vector<int>& nums1, vector<int>& nums2,int s1, int e1, int s2, int e2, int k){
if(s1 == e1){
if(k == ) return min(nums1[s1],nums2[s2]); //为了防止s2+k-1越界
if(nums1[s1] < nums2[s2+k-]) return nums2[s2+k-];
else if(s2+k- == e2) return nums1[s1]; //为了防止s2+k越界
else return min(nums1[s1], nums2[s2+k]);
}
if(s2 == e2){
if(k == ) return min(nums1[s1],nums2[s2]); //为了防止s1+k-1越界
if(nums2[s2] < nums1[s1+k]) return max(nums2[s2],nums1[s1+k-]);
else if(s1+k- == e1) return nums2[s2]; //为了防止s1+k越界
else return min(nums2[s2], nums1[s1+k]);
}
int m1 = s1+((e1-s1)>>);
int m2 = s2+((e2-s2)>>);
int halfLen = (e1 - s1 + e2 - s2 + ) >> ;
if(k > halfLen){ //k is in the second half
if(nums1[m1] < nums2[m2]){ //delete first half of num1
return findK(nums1, nums2, m1+, e1, s2, e2, k-(m1-s1+)); //+1是考虑到m1==s1的情况,注意每次二分至少要去除一个元素
}
else{ //delete fist half of num2
return findK(nums1, nums2, s1, e1, m2+, e2, k-(m2-s2+));//+1是考虑到m2==s2的情况,注意每次二分至少要去除一个元素
}
}
else{ //k is in the first half
if(nums1[m1] < nums2[m2]){ //delete second half of num2
return findK(nums1, nums2, s1, e1, s2, m2, k);
}
else{ //delete second half of num1
return findK(nums1, nums2, s1, m1, s2, e2, k);
}
}
}
};
改进:每次去掉(size1+size2)/2个元素。
假设数组A和B如下,k=6,那么令i=k/2, j =k-k/2
注意: j =k-k/2,保证i+j涵盖整个数组,否则测试用例 [1,2,6] [3,4,5,7,8],k=5的时候将会选取4和6,而不是4和5,原因是在某次比较A[1]和B[1](只有4个,k=5少了一个),选取了A的right subarray[2,6]和B的left subarray[3,4],漏选了Target元素5。如果使用j=k-k/2,那么将会比较A[1]和B[2](5个),从而也会保留B[2]。

B的前三个元素可去掉比较好理解,那么为什么A的后5个元素也能取掉呢?
=>即使B的后7个都比A的前三个大,B的前三个+A的前三个也已经满足k个要求,不需要A的后5个元素了。

class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int len = nums1.size() + nums2.size();
//see out to check null array
if(nums1.empty()){
if(len% == ) return nums2[(len >> )];
else return (double) (nums2[(len >> )-] + nums2[(len >> )])/;
}
if(nums2.empty()){
if(len% == ) return nums1[(len >> )];
else return (double) (nums1[(len >> )-] + nums1[(len >> )])/;
}
if( len% == ) return findK(nums1,,nums1.size()-, nums2, , nums2.size()-,(len >> ));
else {
int m1 = findK(nums1,,nums1.size()-, nums2, , nums2.size()-,(len >> )-);
int m2 = findK(nums1,,nums1.size()-, nums2, , nums2.size()-,(len >> ));
return (double) (m1+m2)/;
}
}
int findK(vector<int>& nums1,int s1,int e1, vector<int>& nums2, int s2, int e2, int k) {
//termination
if(k==) return min(nums1[s1],nums2[s2]);
if(s1==e1 && s2 == e2) {
return max(nums1[s1],nums2[s2]);
}
if(s1 == e1){ // only one element in nums1
if(s2+k > e2){ //prevent overflow
return max(nums1[s1],nums2[e2]);
}
else if(nums1[s1] < nums2[s2+k-]) return nums2[s2+k-];
else if(nums1[s1] < nums2[s2+k]) return nums1[s1];
else return nums2[s2+k];
}
else if(s2 == e2){// only one element in nums2
if(s1+k > e1){ //prevent overflow
return max(nums1[e1],nums2[s2]);
}
else if( nums2[s2] < nums1[s1+k-]) return nums1[s1+k-];
else if(nums2[s2] < nums1[s1+k]) return nums2[s2];
else return nums1[s1+k];
}
//make the length of first half of m1 + first half of m2 = k
int m1 = s1 + (k >> );
if(m1 > e1){ //check overflow
m1 = e1;
}
int m2 = s2 + k - (m1-s1+);
if(m2 > e2){ //check overflow
m2 = e2;
m1 = s1 + k - (m2-s2+);
}
if((m1 == s1 && m2 == e2) || (m1==e1 && m2==s2)){
//try to make k-1
if(nums1[s1] < nums2[s2]) return findK(nums1,s1+,e1,nums2,s2,e2,k-);
else return findK(nums1,s1,e1,nums2,s2+,e2,k-);
}
//compare two arrays
if(nums1[m1]<nums2[m2]){ //remove first half of num1 and second half of num2
return findK(nums1,m1,e1,nums2,s2,m2,k-(m1-s1)); //need to guarantee ! (m1==s1 && m2==e2)
}
else{//remove first half of num2 and second half of num1
return findK(nums1,s1,m1,nums2,m2,e2,k-(m2-s2)); // need to guarantee ! (m1==e1 && m2==s2)
}
}
};
4. Median of Two Sorted Arrays(Array; Divide-and-Conquer)的更多相关文章
- 【转载】两个排序数组的中位数 / 第K大元素(Median of Two Sorted Arrays)
转自 http://blog.csdn.net/zxzxy1988/article/details/8587244 给定两个已经排序好的数组(可能为空),找到两者所有元素中第k大的元素.另外一种更加具 ...
- 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays
一道非常经典的题目,Median of Two Sorted Arrays.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/ ...
- [LintCode] Median of Two Sorted Arrays 两个有序数组的中位数
There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...
- LeetCode 4 Median of Two Sorted Arrays (两个数组的mid值)
题目来源:https://leetcode.com/problems/median-of-two-sorted-arrays/ There are two sorted arrays nums1 an ...
- Kotlin实现LeetCode算法题之Median of Two Sorted Arrays
题目Median of Two Sorted Arrays(难度Hard) 方案1,数组合并&排序调用Java方法 import java.util.* class Solution { fu ...
- 【LeetCode】4. Median of Two Sorted Arrays (2 solutions)
Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. Find t ...
- LeetCode: Median of Two Sorted Arrays 解题报告
Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. Find t ...
- 《LeetBook》leetcode题解(4): Median of Two Sorted Arrays[H]——两个有序数组中值问题
我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...
- LeetCode 004 Median of Two Sorted Arrays
题目描述:Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. F ...
随机推荐
- 1005 Spell It Right (20 分)
1005 Spell It Right (20 分) Given a non-negative integer N, your task is to compute the sum of all th ...
- Java 运算符-=,+=混合计算详解
+=与-=运算符混合计算解析: int x = 3; x += x -= x -= x += x -= x; 详解:算数运算按运算符优先级运算,从右至左计算. 1. x=x-x; 实际为 3 - 3 ...
- orm 小结
1. 销售注册,登录系统 - 用户表 2.销售添加客户信息,成为销售的私户 - 客户表 3. 销售固定时间跟进客户 - 跟进记录表 4. 客户报名 - 报名记录表 - 班级表(必须 ...
- Redis如何存储对象与集合示例详解
前言 大家都知道在项目中,缓存以及mq消息队列可以说是不可或缺的2个重要技术.前者主要是为了减轻数据库压力,大幅度提升性能.后者主要是为了提高用户的体验度,我理解的是再后端做的一个ajax请求(异 ...
- Bogart gGrid.vb
Namespace BogartMis.Cls Public Class gGrid '設定表格控的列標題的別名 '說明:strItem字符串的格式為"01,02,03,04,05" ...
- Laravel 5.4: 特殊字段太长报错
laravel 5.4 改变了默认的数据库字符集,现在utf8mb4包括存储emojis支持.如果你运行MySQL v5.7.7或者更高版本,则不需要做任何事情. 当你试着在一些MariaDB或者一些 ...
- uva-10152-乌龟排序
求从待排序的到期望的顺序的最小操作顺序,只能进行一个操作,将当前的乌龟拿出来,上面的下移,拿出来的放到最上面 发现voj没有PE, 解题方法,把俩个串反过来使用,从期望的顺序到待排序的顺序. AC:1 ...
- 温故而知新-正则单词和strlen
1 正则表达式用\b表示单词的开始和结束 \bblog\b 正则查找blog这个单词 2 关于strlen的汉字问题 在utf8格式下 strlen('汉字')=6 在gbk格式下 strlen(' ...
- 玩转laravel5.4的入门动作(二)
做个文章的增删改查 第一步 把数据库的表结构建好,生成迁移 1 怎么建,当然是用php artisan命令了 使用 Artisan 命令 make:migration 来创建一个新的迁移: php ...
- Spring Boot 入门搭建
一.前言 Spring Boot 的设计目的是用来简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. 二.环境搭建 创建一个 ...