LeetCode 4. 寻找两个正序数组的中位数

在这里插入图片描述
https://leetcode-cn.com/problems/median-of-two-sorted-arrays/

解题思路:使用两层二分查找

    public class Solution
    {
    	//数组中小于target的数字数量
        int SearchLeftCount(int target, int[] numbers) {
            int left =  0;
            int right = numbers.Length;
            while (left < right) {
                int mid = (left + right) >> 1;
                if (target <= numbers[mid]) {
                    right = mid;
                } else {
                    left = mid + 1;
                }
            }
            return left;
        }
		//数组中大于target的数字数量
        int SearchRightCount(int target, int[] numbers) {
            int left = 0;
            int right = numbers.Length;
            while (left < right) {
                int mid = (left + right) >> 1;
                if (numbers[mid] <= target) {
                    left = mid + 1;
                }
                else {
                    right = mid;
                }
            }
            return numbers.Length - left;
        }
		
		//数组中与target相同的数字数量
        public int SearchSameCount(int target, int[] numbers) {
            int leftCount = SearchLeftCount(target, numbers);
            int rightCount = SearchRightCount(target, numbers);
            return numbers.Length - leftCount - rightCount;
        }
		//在nums1中查找nums1和nums2的中位数,offset用于查找第二个中位数
        double? SearchMidNumber(int[] nums1, int[] nums2, int offset = 0) {
            double? result = null;
            int left = 0;
            int right = nums1.Length;
            int numberCount = nums1.Length + nums2.Length;
            //中位数是第几个数
            int targetIndex = ((numberCount + 1) >> 1) + offset;
            while (left < right) {
                int mid = (left + right) >> 1;
                //nums1中等于nums1[mid]的左开右闭区间
                int left1 = SearchLeftCount(nums1[mid], nums1);
                int right1 = nums1.Length - SearchRightCount(nums1[mid], nums1);
                //nums2中等于nums1[mid]的左开右闭区间
                int left2 = SearchLeftCount(nums1[mid], nums2);
                int right2 = nums2.Length - SearchRightCount(nums1[mid], nums2);
                if (left1 + left2 < targetIndex && targetIndex <= right1 + right2) {
                	//在区间内nums1[mid]就是中位数
                    result = nums1[mid];
                    break;
                }
                else if (targetIndex <= left1 + left2) {
                    right = left1;
                }
                else if (right1 + right2 < targetIndex) {
                    left = right1;
                }

            }
            if (null == result) {
                return null;
            }
            if (0 == offset && ((nums1.Length + nums2.Length) & 1) != 1) {
                //偶数要求出两个中位数再求平均值
                double? result1 = SearchMidNumber(nums1, nums2, 1);
                if (null == result1) {
                    result1 = SearchMidNumber(nums2, nums1, 1);
                }
                if (null == result1) {
                    return null;
                }
                return (result.Value + result1.Value) / 2;
            }
            return result;
        }

        public double FindMedianSortedArrays(int[] nums1, int[] nums2) {
        	//先在nums1中找第一个数
            double? result = SearchMidNumber(nums1, nums2);
            if (null == result) {
	            //在nums2中找第一个数
                result = SearchMidNumber(nums2, nums1);
            }
            return result.Value;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

achonor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值