问题一:两个有序数组,且长度都为n。找出中位数。
解决这个问题的方法很多。
方法一:基于归并排序的merge方法。找出两个数组中第n大的数和第n+1大的数,然后求它们的平均数。时间复杂度为O(n)。
方法二:比较两个数组中的中位数的大小。每一次比较都能缩小两个数组的搜索范围。时间复杂度为O(nlgn)。
public static double findMedianInSameLength(
int[] a, int la, int ra, int[] b, int lb,int rb) {
assert(a.length == b.length);
if (a.length == 1) {
return (double)(a[0] + b[0])/2;
}
int ma = la + (ra - la)/2;
int mb = lb + (rb - lb + 1)/2;
if ((ra - la) == 1 && (rb - lb) == 1) {
return (double)(max(a[la], b[lb]) + min(a[ra], b[rb]))/2;
}
if (a[ma] > b[mb]) {
return findMedianInSameLength(a, la, ma, b, mb, rb);
}
if (a[ma] < b[mb]) {
return findMedianInSameLength(a, ma, ra, b, lb, mb);
}
return a[ma];
}
private static int min(int i, int j) {
return i < j ? i : j;
}
private static int max(int i, int j) {
return i > j ? i : j;
}
方法三:基于二分搜索的方法。
public static double findMedianWithBinarySearch(int[] a, int[] b) {
assert(a.length == b.length);
if (a[a.length - 1] <= b[0]) {
return (double)(a[a.length - 1] + b[0])/2;
}
if (a[0] >= b[b.length - 1]) {
return (double)(a[0] + b[b.length - 1])/2;
}
return findMedianCore(a, 0, a.length - 1, b);
}
private static double findMedianCore(
int[] a, int left, int right, int[] b) {
if (left > right) {
return findMedianCore(b, 0, b.length-1, a);
}
int n = (a.length + b.length)>>1;
int i = left + ((right - left)>>1);
int j = n - i - 1;
if (a[i] == b[j]) {
return (double)a[i];
}
else if (a[i] > b[j] && (j == b.length - 1 || a[i] <= b[j+1])) {
if (!isOdd(a, b)) {
if (i == 0 || a[i-1] < b[j]) {
return (double)(a[i] + b[j])/2;
}
else {
return (double)(a[i] + a[i - 1])/2;
}
}
else {
return (double)a[i];
}
}
else if (a[i] > b[j] && j != b.length - 1 && a[i] > b[j+1]) {
return findMedianCore(a, left, i-1, b);
}
else {
return findMedianCore(a, i+1, right, b);
}
}
private static boolean isOdd(int[] a, int[] b) {
return ((a.length + b.length) & 0x1) > 0;
}
问题二:假如两个有序数组的长度不同。找出中位数。
这个问题同样可以用问题一中的方法三来解决。
public static double findMedian(int[] a, int[] b) {
if (a[a.length - 1] <= b[0] ) {
if (isOdd(a, b)) {
if (a.length > b.length) {
return (double)a[(a.length+b.length)>>1];
}else {
return (double)b[(b.length-a.length)>>1];
}
}else {
if (a.length > b.length) {
int index1 = (a.length+b.length)>>1;
int index2 = ((a.length+b.length)>>1)-1;
System.out.println(a[index1] + " " + a[index2] + " " + (double)(a[index1]+a[index2])/2);
return (double)(a[index1]+a[index2])/2;
}else if (a.length < b.length) {
return (double)(b[(b.length-a.length)>>1]+b[((b.length-a.length)>>1)-1])/2;
}else {
return (double)(a[a.length - 1] + b[0])/2;
}
}
}
if (a[0] >= b[b.length - 1]) {
if (isOdd(a, b)) {
if (a.length < b.length) {
return (double)b[(a.length+b.length)>>1];
}else {
return (double)a[(a.length-b.length)>>1];
}
}else {
if (a.length < b.length) {
return (double)(b[(a.length+b.length)>>1]+a[((a.length+b.length)>>1)-1])/2;
}else if (a.length > b.length) {
return (double)(a[(b.length-a.length)>>1]+a[((b.length-a.length)>>1)-1])/2;
}else {
return (double)(a[0] + b[b.length - 1])/2;
}
}
}
return findMedianCore(a, 0, a.length - 1, b);
}
private static double findMedianCore(
int[] a, int left, int right, int[] b) {
if (left > right) {
return findMedianCore(b, 0, b.length-1, a);
}
int n = (a.length + b.length)>>1;
int i = left + ((right - left)>>1);
int j = n - i - 1;
if (a[i] == b[j]) {
return (double)a[i];
}
else if (a[i] > b[j] && (j == b.length - 1 || a[i] <= b[j+1])) {
if (!isOdd(a, b)) {
if (i == 0 || a[i-1] < b[j]) {
return (double)(a[i] + b[j])/2;
}
else {
return (double)(a[i] + a[i - 1])/2;
}
}
else {
return (double)a[i];
}
}
else if (a[i] > b[j] && j != b.length - 1 && a[i] > b[j+1]) {
return findMedianCore(a, left, i-1, b);
}
else {
return findMedianCore(a, i+1, right, b);
}
}
private static boolean isOdd(int[] a, int[] b) {
return ((a.length + b.length) & 0x1) > 0;
}
分享到:
相关推荐
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。 你可以假设 nums1 和 nums2 不会同时为空。 示例 1: nums1 = [1, 3] nums2 = [2] 则中位数是 2.0 示例 2: nums1 = [1, 2] ...
探寻两个有序数组中位数题目的思路探讨与源码 探寻两个有序数组中位数的题目如下图,该题属于数组类的题目,主要考察对于中位数的理解,通过考虑不同两个数组的相对位置情况,最终求出中位数。本人的思路比较懒,...
(1)设X[0:n-1]和Y[0:n-1]为两个数组,每个数组中含有n个已排好序的数,设计一个算法复杂度为O(logn)的分治算法,找出X和Y中2n个数中的中位数。(中位数:个数为奇数:中间位置上的数;个数为偶数,中间两个数的...
4. 寻找两个有序数组的中位数给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O
# 请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) # 你可以假设 nums1 和 nums2 不同时为空 # 示例 1: # nums1 = [1, 3] # nums2 = [2] # 中位数是 2.0 # 示例 2: # nums1 = [1, 2] # nums2 ...
刷题:给两个有序的数组,找出合并后的中位数
算法/编程练习:两个有序数组的中位数 题目来自LeetCode: https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 题目: 给定两个大小为 n1 和 n2 的有序(升序)数组 nums1 和 nums2 , 找出这两个有序...
Python寻找两个有序数组的中位数 审题: 1.找出意味着这是一个查找算法题 2.算法复杂度log级别,就是提示你是二分查找 3.二分查找实现一般为递归 (1)递归包括递归体 (2)终止条件 思路: 定理: 1.有序数组...
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。 你可以假设 nums1 和 nums2 不会同时为空。 示例1: nums1 = [1, 3] nums2 = [2] 则中位数是 2.0 示例2: nums1 = [1, 2] nums...
代码实现://无论在总个数为奇数还是偶数k为其mid坐标,如果是偶数个K为后面的那个mid//将两个数组中相对小的那个数压入新数组思路:采用分治算法,将两个数组
示例 1:则中位数是 2.0示例 2:则中位数是 (2 + 3)/2 = 2.5一开始的想法这道题没做出来,因为我对复杂度掌握还不好,无法从一个复杂度想到某种思
无法登录两个有序数组的中位数 LeetCode 中“无重复字符的最长子串”问题的解决方法。 问题 有两个大小分别为 m 和 n 的排序数组 nums1 和 nums2。 找出两个已排序数组的中位数。 整体运行时间复杂度应该是 O(log (m...
请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。 你可以假设 nums1 和 nums2 不同时为空。 示例 1: nums1 = [1, 3] nums2 = [2] 中位数是 2.0 示例 2: nums1 = [1, 2] nums2 = [3, 4...
实现了求两个等长数组中位数的算法,利用C++语言实现
还是暴力法,不过不用新数组,而是用两个指针和一个变量来求第k小的数,k=(m+n)/2 3.用二分法来求第k小的数,如果m+n是偶数,则求第k和第k+1小的平均值。 */ class Solution { public double ...
具体来说,假设待合并的两个有序数组分别为A和B,它们的长度分别为n和m,合并后的有序数组为C,那么合并的过程可以按如下步骤进行: 1. 定义三个指针i、j和k,分别指向数组A、B和C的起始位置。 2. 比较A[i]和B[j]的...
无法登录两个有序数组的中位数 问题 有两个大小分别为 m 和 n 的排序数组 nums1 和 nums2。求两个排序数组的中位数。 整体运行时间复杂度应该是 O(log (m+n))。 您可以假设 nums1 和 nums2 不能都为空。 例子 nums1 ...