leetcode二分困难题

8 阅读1分钟

4. 寻找两个正序数组的中位数 - 力扣(LeetCode)

image.png

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            return find(nums2, nums1);
        } else {
            return find(nums1, nums2);
        }
    }

    public double find(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        int total = m + n;
        int half = total / 2;
        

        // 修正:l 和 r 的初始值,覆盖 [0, m] 区间
        int l = 0, r = m;
        
        while (true) {
            // 从 nums1 中取 i 个元素到左边
            int i = (l + r) / 2;
            // 从 nums2 中取 (half - i) 个元素到左边,使左边总数为 half
            int j = half - i;
            
            // 处理边界值
            int nums1Left = (i > 0) ? nums1[i-1] : Integer.MIN_VALUE;
            int nums1Right = (i < m) ? nums1[i] : Integer.MAX_VALUE;
            int nums2Left = (j > 0) ? nums2[j-1] : Integer.MIN_VALUE;
            int nums2Right = (j < n) ? nums2[j] : Integer.MAX_VALUE;
            
            if (nums1Left <= nums2Right && nums2Left <= nums1Right) {
                // 奇数情况:返回右边最小元素
                if (total % 2 != 0) {
                    return (double) Math.min(nums1Right, nums2Right);
                }
                // 偶数情况:返回左右两边中位数的平均
                else {
                    return (double) (Math.max(nums1Left, nums2Left) + Math.min(nums1Right, nums2Right)) / 2.0;
                }
            } else if (nums1Left > nums2Right) {
                // nums1 左边元素太大,划分线左移
                r = i - 1;
            } else {
                // nums2 左边元素太大,划分线右移
                l = i + 1;
            }
        }
    }
}