`
jgsj
  • 浏览: 961391 次
文章分类
社区版块
存档分类
最新评论

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 the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

感觉本题并不难,如果用简单的方法做的话,好像很容易就通过了。

比如合并成一个数组,然后排序,然后直接返回中间数,也可以通过的,如下程序:

double findMedianSortedArrays(int A[], int m, int B[], int n) {
		vector<int> vab(A, A+m);
		for (int i = 0; i < n; i++)
		{
			vab.push_back(B[i]);
		}
		sort(vab.begin(), vab.end());
		int k = (m+n)/2;
		float fk = float(m+n)/2.0;
		float fk2 = float(k);
		if(fk != fk2)
		{
			return vab[k];
		}
		return double(vab[k-1] + vab[k]) / 2.0;
	}


这就没有利用的原理两个数列是已经排序好的特点了,所以需要优化一下。

就是利用截断法原理,每次递归截断一定元素。

本题目就是选取两个数列的中间k/2个元素,要很小心选取这个元素,要诀就是:不要截去的太快了,不然结果就会不正确的。如果截去太快了,就要-1,截去慢一点。看看下面的程序就知道了。

这里有程序查找任意数列中的第K大元素:http://blog.csdn.net/kenden23/article/details/14645619

不同的是这里要利用好原数列特点。

double findMedianSortedArrays(int A[], int m, int B[], int n) {
		int mn = m + n;
		if (0 == mn % 2) 
		{
			return (selectKthNum(A, m, B, n, mn/2-1) + selectKthNum(A, m, B, n, mn/2)) / 2.0;
		} 
		else 
		{
			return selectKthNum(A, m, B, n, mn/2);
		}
	}

	double selectKthNum(int A[], int m, int B[], int n, int k)
	{
		if (m > n) return selectKthNum(B, n, A, m, k);
		if (0 >= m) return B[k];
		if (0 >= n) return A[k];
		if (0 == k) return min(A[0], B[0]);

		int a = min(k/2, m-1);
		int b = k - a - 1;//这里不是k-a,是为了不要截得太快了,不然会出错。
		if (A[a] < B[b]) 
		{
			return selectKthNum(A + a + 1, m - a - 1, B, n, k - a - 1);
		} 
		else 
		{
			return selectKthNum(A, m, B + b +1, n - b -1, k - b -1);
		}
	}

也可以像这样处理下标:

double findMedianSortedArrays3(int A[], int m, int B[], int n) {
		int mn = m + n;
		if (0 == mn % 2) 
		{
			return (selectKthNum(A, m, B, n, mn/2-1) + selectKthNum(A, m, B, n, mn/2)) / 2.0;
		} 
		else 
		{
			return selectKthNum(A, m, B, n, mn/2);
		}
	}

	double selectKthNum(int A[], int m, int B[], int n, int k)
	{
		if (m > n) return selectKthNum(B, n, A, m, k);
		if (0 >= m) return B[k];
		if (0 >= n) return A[k];
		if (0 == k) return min(A[0], B[0]);

		int a = min((k-1)/2, m-1);//这里一定要k-1,否则截去太快了,结果会出错。
		if (A[a] < B[a]) 
		{
			return selectKthNum(A + a + 1, m - a - 1, B, n, k - a - 1);
		} 
		else 
		{
			return selectKthNum(A, m, B + a +1, n - a -1, k - a -1);
		}
	}


所以要理解这里的截去原理!

下标处理很麻烦,看看下面LeetCode论坛上的下标处理也许处理的更加好:

class Solution {
public:
	double findMedianSortedArrays(int A[], int m, int B[], int n) {
		int total = m + n;
		if (0 == total % 2) {
			return (FindKth(A, m, B, n, total/2) + FindKth(A, m, B, n, total/2 + 1)) / 2;
		} else {
			return FindKth(A, m, B, n, total/2 + 1);
		}
	}

	double FindKth(int A[], int m, int B[], int n, int k) {
		if (m > n) return FindKth(B, n, A, m, k);
		if (0 == m) return B[k-1];
		if (0 == n) return A[k-1];
		if (1 == k) return min(A[0], B[0]);

		int aMid = min(k/2, m);
		int bMid = k - aMid;
		if (A[aMid-1] < B[bMid-1]) {
			return FindKth(A + aMid, m - aMid, B, n, k - aMid);
		} else {
			return FindKth(A, m, B + bMid, n - bMid, k - bMid);
		}
	}
};



也可以用查找一般第K大的数的程序完成这道题,也是可以通过的:

double findMedianSortedArrays(int A[], int m, int B[], int n) 
	{
		vector<int> vab(A, A+m);
		for (int i = 0; i < n; i++)
		{
			vab.push_back(B[i]);
		}

		int k = (m+n)/2;
		float fk = float(m+n)/2.0;
		float fk2 = float(k);
		double d1;
		if(fk != fk2)
		{
			d1 = selectKthNumRand(vab, 0, vab.size()-1, k+1);
			return d1;
		}
		int k1 = k+1;
		d1 = selectKthNumRand(vab, 0, vab.size()-1, k1);
		double d2   = selectKthNumRand(vab, 0, vab.size()-1, k);
		return double(d1+d2) / 2.0;
	}

	int selectKthNumRand(vector<int> &vi, int low, int up, int k)
	{
		int mIndex;

		//注意这里会有几率是up=0, low=0,所以要作特殊处理
		if(up-low != 0)
			mIndex = rand()%(up-low) + low;
		else mIndex = 0;
		int mNum = vi[mIndex];

		vector<int> vec1, vec2, vec3;
		for (int i = low; i <= up; i++)
		{
			if(vi[i] > mNum) vec3.push_back(vi[i]);
			if(vi[i] == mNum) vec2.push_back(vi[i]);
			if(vi[i] < mNum) vec1.push_back(vi[i]);
		}

		if(vec1.size()>=k) 
			return selectKthNumRand(vec1, 0, vec1.size()-1, k);
		else if(vec1.size()+vec2.size()>=k) 
			return mNum;
		else if(vec1.size()+vec2.size()<k) 
			return selectKthNumRand(vec3, 0, vec3.size()-1, k-vec1.size()-vec2.size());
	}


2014-1-23 update继续重写更新,其实是很简单的一个二分法的灵活运用:

	double findMedianSortedArrays(int A[], int m, int B[], int n) 
	{
		int k = (m+n)>>1;
		if ((m+n)%2) return findKthElement(A, m, B, n, k+1); 
		return (findKthElement(A, m, B, n, k)+findKthElement(A, m, B, n, k+1))/2;
	}

	double findKthElement(int A[], int m, int B[], int n, int k)
	{
		if (m==0) return B[k-1];//if (!A) return B[k-1];这样写居然是会编译错误的
		if (n==0) return A[k-1];//if (B==NULL) return A[k-1];
		if (k==1) return A[0]<B[0]? A[0]:B[0];

		int mid = (k>>1);
		mid = min(min(m,mid),n);
		k -= mid;
		if (A[mid-1] < B[mid-1])
			return findKthElement(A+mid, m-mid, B, n, k);
		else return findKthElement(A, m, B+mid, n-mid, k);
	}


分享到:
评论

相关推荐

    LeetCode4 Median of Two Sorted Arrays

    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)). Java AC版本

    leetcode无法登录-MedianOfTwoSortedArrays:双排序数组的中位数

    leetcode 无法登录两个有序数组的中位数 问题 有两个大小分别为 m 和 n 的排序数组 nums1 和 nums2。求两个排序数组的中位数。 整体运行时间复杂度应该是 O(log (m+n))。 您可以假设 nums1 和 nums2 不能都为空。 ...

    程序员面试宝典LeetCode刷题手册

    4. Median of Two Sorted Arrays 7. Reverse Integer 9. Palindrome Number 11. Container With Most Water 13. Roman to Integer 15. 3Sum 16. 3Sum Closest 17. Letter Combinations of a Phone Number 18. 4Sum ...

    leetcodepython001-algorithm:leetcode问题(cpp、java、python),书籍破解_the_coding

    leetcode Python 001 leetcode的算法问题 这是我的解决方案,用 cpp 、 java 和 python 编写 #LeetCode 解决的问题: 001. Two Sum 002. Add Two Numbers 003. Longest Substring Without Repeating Characters4. ...

    lrucacheleetcode-leetcode:leetcode

    lru缓存leetcode leetcode 1. Two Sum 2. Add Two Numbers 3. Longest Substring Without Repeating Characters 4. Median of Two Sorted Arrays 5. Longest Palindromic Substring 7. Reverse Integer 9. ...

    leetcodepython001-leetcode:https://leetcode.com/的解决方案

    leetcode Python 001 力码 ├── Algorithms │  ├── cpp │  │  ├── 001 - Two Sum.cpp │  │  ├── 002 - Add Two Numbers.cpp │  │  ├── 003 - Longest Substring Without Repeating ...

    Coding Interview In Java

    7 Median of Two Sorted Arrays 33 8 Kth Largest Element in an Array 35 9 Wildcard Matching 37 10 Regular Expression Matching in Java 39 11 Merge Intervals 43 12 Insert Interval 45 13 Two Sum 47 14 Two ...

    leetcode分类-leetcode:leetcode问题的代码

    leetcode 分类leetcode 问题分类 leetcode代码仓库,我的解题思路写在我的博客里: leetcode 代码库,我博客上的解题思路: mkdir 列表: 大批 #1:Two Sum #4:Median of Two Sorted Arrays 地图 #1:Two Sum #3:...

    leetcode双人赛-LeetCode:力扣笔记

    leetcode双人赛LeetCode 编号 题目 难度 题型 备注 Two Sum 简单 Add Two Numbers 中等 链结串列 重要 Longest Substring Without Repeating Characters 中等 字串 重要 Median of Two Sorted Arrays 困难 数学 ...

    javalruleetcode-Leetcode:力码解决方案

    (两数之和) Easy Hash Table 2 Add Two Numbers (两数相加) Medium Linked List 3 Longest Substring Without Repeating Characters (无重复字符的最长子串) Medium Dual Pointer (Sliding Window), Hash Table 4 ...

    leetcode2-Leetcode:Leetcode_answer

    leetcode 2 Leetcode答案集 关于项目: 本项目包含本人LeetCode解题的答案,全部将由JavaScript语言进行解答。并会在每个题目的文件夹中添加相关的思路解析。 详情 # Title Solution Time Space Difficulty 1 Two ...

    leetcode分类-LeetCodeSrc:力扣

    leetcode分类LeetCodeSourceCodes###LeetCode1TowSum如果数组是有序的,O(n)的时间复杂度就可以解决了,现在是无序的,一开始要排一下序###LeetCode2MedianofTwoSortedArrays让用logn的时间复杂度,用了两个二分,...

    javalruleetcode-LeetCode::lollipop:个人LeetCode习题解答仓库-多语言

    Median of Two Sorted Arrays 5 Longest Palindromic Substring 8 String to Integer 11 Container with Most Water 14 Longest Common Prefix 15 Three Sum 16 Three Sum Closest 20 Valid Parentheses 26 Remove ...

    leetcode题库-LeetCode:力码

    leetcode题库 LeetCode 题解合集 本仓库展示了LeetCode题库中部分题目的解法(持续更新),所有代码均采用C++编写并配有输入输出样例 代码清单如下: 序号 题目 程序源码 1 两数之和 Two Sum.cpp 2 两数相加 Add Two...

    leetcode题库-LeetCode-Go:用GO回答LeetCode

    leetcode题库 LeetCode-Go 理论基础 见Note 脑图 TODO 待填充 算法题 面试高频出现,以及一些非常经典重要的算法题优先 题目列表 No Title Link Solution Acceptance Difficulty Topics Solution 0001 Two Sum 46.1%...

    leetcode338-LeetCode:LeetCode刷题总结

    LeetCode刷题总结 1.Two Sum 2.Add Two Numbers 3.Longest Substring Without Repeating Characters 4.Median of Two Sorted Arrays 5.Longest Palindromic Substring (Manacher算法待完成) 6.ZigZag Conversion 7....

    lrucacheleetcode-leetcode-1:leetcode-1

    求两有序数列的中位数,可泛化为求两有序数列的第k位数,二分法 5. Longest Palindromic Substring 最长回文子串,补符号,记忆 6. ZigZag Conversion 观察规律 7. Reverse Integer 翻转整数 8. String to Integer ...

    leetcode跳跃-LeCode:乐科

    leetcode 跳跃 LeetCode Solved by Python easy/middle/hard:15/36/5 1. Two Sum 两数之和 2. Add Two Numbers 两数相加 3. Longest Substring Without Repeating Characters 无重复字符的最长子串 4. Median of ...

    分割数组求最大差值leetcode-Leetcode-Road:LeetCode刷题记录

    分割数组求最大差值leetcode LeetCode 学习之路 记录自己完成LeetCode的代码和结果。 序号 中文名称 英文名称 通过率 难度 1 Two Sum 47.0% 简单 2 Add Two Numbers 36.0% 中等 3 Longest Substring Without ...

    Leetcode回文串拼接-leetcode_note:用于记录leetcode题目的解析

    Leetcode回文串拼接 leetcode_node 题解 该项目主要用于基于Leetcode的刷题记录,与日常学习,对Leetcode上的题目按照解题方法进行分明别类的整理。 题目列表 1.Two Sum 2.Add Two Numbers 3.Longest Substring ...

Global site tag (gtag.js) - Google Analytics