减治算法之寻找两个递增序列的中位数

一、问题描述

寻找两个递增序列的中位数。

本算法中只能解决两个序列长度规模相等的问题,若两个序列长度规模不相等,则可以先做合并(leetcode:Merge Sorted Array 【Java】)后再寻找中位数。

二、问题分析

分别计算序列A,B的中位数a,b


比较中位数a,b,会出现以下三种请款

(1)a = b,直接返回结果a

(2)a < b,两个序列的中位数只能出现在[a,b),在序列中A中删除a之前的元素形成新序列A,在序列B中删除b之后的元素形成新序列B

(3)a > b,两个序列的中位数只能出现在[b,a),在序列中A中删除a之后的元素形成新序列A,在序列B中删除b之前的元素形成新序列B


重复以上步骤。

三、算法代码

public static int searchMid(int [] a, int [] b){
		if(a.length != b.length){
			System.out.println("序列规模不一致,计算结果初始化为-1!");
			return -1;
		}
		int s1 = 0;
		int e1 = a.length - 1;
		int s2 = 0;
		int e2 = b.length - 1;
		int mid1,mid2;
		while(s1 < e1 && s2 < e2){
			mid1 = (s1 + e1) / 2;
			mid2 = (s2 + e2) / 2;
			if(a[mid1] == b[mid2]){
				return a[mid1];
			}
			if(a[mid1] < b[mid2]){
				s1 = mid1 + 1;
				e2 = mid2;
			}else{
				s2 = mid2 + 1;
				e1 = mid1;
			}
		}
		if(a[s1] < b[s2]){
			return a[s1];
		}else{
			return b[s2];
		}
	}
四、完整测试代码

public class package01 {

	public static void main(String [] args){
		int [] a = new int[]{1,2,3,4,5,11,13};
		int [] b = new int[]{6,7,8,9,10,12,14};
		int result = searchMid(a, b);
		System.out.print("两个递增序列的中位数为:" + result);
	}

	public static int searchMid(int [] a, int [] b){
		if(a.length != b.length){
			System.out.println("序列规模不一致,计算结果初始化为-1!");
			return -1;
		}
		int s1 = 0;
		int e1 = a.length - 1;
		int s2 = 0;
		int e2 = b.length - 1;
		int mid1,mid2;
		while(s1 < e1 && s2 < e2){
			mid1 = (s1 + e1) / 2;
			mid2 = (s2 + e2) / 2;
			if(a[mid1] == b[mid2]){
				return a[mid1];
			}
			if(a[mid1] < b[mid2]){
				s1 = mid1 + 1;
				e2 = mid2;
			}else{
				s2 = mid2 + 1;
				e1 = mid1;
			}
		}
		if(a[s1] < b[s2]){
			return a[s1];
		}else{
			return b[s2];
		}
	}
}
五、运行结果

两个递增序列的中位数为:8




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
给定两个递增的整数序列A和B,我们可以使用分治法来找出它们的中位数。 首先,我们可以计算出两个序列的总长度n,然后找到两个序列中的第n/2个元素(假设索引从0开始)。如果n是奇数,则中位数就是这两个元素中的较小值;如果n是偶数,则中位数就是这两个元素的平均值。 接下来,我们可以比较A和B中的第n/2个元素。如果A[n/2]小于B[n/2],则说明A的前半部分和B的后半部分的元素都不可能是中位数,可以将它们排除。同样地,如果A[n/2]大于B[n/2],则说明A的后半部分和B的前半部分的元素都不可能是中位数,可以将它们排除。最后,如果A[n/2]等于B[n/2],则说明找到了中位数。 如果A或B的长度为0,则中位数就是另一个序列的第n/2个元素。 通过不断缩小问题规模,我们可以在O(log n)的时间复杂度内找到两个序列中位数。 代码示例(Python): ```python def findMedianSortedArrays(nums1, nums2): m, n = len(nums1), len(nums2) if m > n: nums1, nums2, m, n = nums2, nums1, n, m imin, imax, half_len = 0, m, (m + n + 1) // 2 while imin <= imax: i = (imin + imax) // 2 j = half_len - i if i < m and nums2[j - 1] > nums1[i]: imin = i + 1 elif i > 0 and nums1[i - 1] > nums2[j]: imax = i - 1 else: if i == 0: max_of_left = nums2[j - 1] elif j == 0: max_of_left = nums1[i - 1] else: max_of_left = max(nums1[i - 1], nums2[j - 1]) if (m + n) % 2 == 1: return max_of_left if i == m: min_of_right = nums2[j] elif j == n: min_of_right = nums1[i] else: min_of_right = min(nums1[i], nums2[j]) return (max_of_left + min_of_right) / 2.0 ``` 这个算法的时间复杂度为O(log(min(m, n))),其中m和n分别为两个序列的长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值