LeetCode第4题:寻找两个有序数组的中位数C语言实现

解法一
  1. 先找到两个数组的长度, 然后遍历找到中位数即可
  2. 如果是奇数个, 那么就直接返回, 如果是偶数个, 那么就返回它与它前一个树的和的平均数
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
    int target = (nums1Size + nums2Size) >> 1;
    int i, j, pre, res;// pre记录res前边的一个数, res为返回结果
    i = j = pre = res = 0;
    // 判读跳出循环是因为一个数组到尽头了还是找到中位数了
    int flag = 0; 
    // 计数器, 找到中位数
    int count = -1;
    while (i < nums1Size && j < nums2Size) {
        pre = res;
        res = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++];
        count++;
        if (count == target) {
            flag = 1;
            break;
        }
    }
    if (!flag) {
        while (count != target) {
            pre = res;
            res = (i == nums1Size) ? nums2[j++] : nums1[i++];
            count++;
        }
    }
    return (nums1Size + nums2Size) & 1 ? res * 1.0 : (pre + res) * 1.0 / 2;
}

复杂度分析: 假设两个数组长度分别为m, n, 本算法的遍历次数为(n + m) / 2, 所以复杂度为O(m + n)

解法二

算法思想:

  1. 使用二分思想
  2. 本题相当于在两个有序数组中查找中位数, 可以使用二分方法依次排除不可能的取值
  3. 假设查找值为k, 那么A[0-k/2]和B[0-k/2]绝对不会是结果, 我们可以利用这个性质, 递归求得结果
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
    int k, flag = 0;
    flag = (nums1Size + nums2Size) & 1;
    if (!nums1Size) return flag ? nums2[(nums2Size >> 1)] : (nums2[(nums2Size) >> 1] + nums2[((nums2Size) >> 1) - 1]) * 1.0 / 2;
    if (!nums2Size) return flag ? nums1[(nums1Size >> 1)] : (nums1[(nums1Size) >> 1] + nums1[((nums1Size) >> 1) - 1]) * 1.0 / 2;
    k = flag ? ((nums1Size + nums2Size) >> 1) + 1 : ((nums1Size + nums2Size) >> 1);
    int a1 = 0, a2 = 0;
    while (k > 1) {
        int offset = (k >> 1) - 1;
        offset = a1 + offset >= nums1Size ? nums1Size - a1 - 1 : offset;
        offset = a2 + offset >= nums2Size ? nums2Size - a2 - 1 : offset;
        a1 += offset;
        a2 += offset;
        if (nums1[a1] <= nums2[a2]) {
            a1 += 1;
            a2 -= offset;
        } else {
            a1 -= offset;
            a2 += 1;
        }
        k = k - (offset + 1);
        if (a1 >= nums1Size) return flag ? nums2[a2 + k - 1] : (nums2[a2 + k - 1] + nums2[a2 + k]) * 1.0 / 2;
        if (a2 >= nums2Size) return flag ? nums1[a1 + k - 1] : (nums1[a1 + k - 1] + nums1[a1 + k]) * 1.0 / 2;
    }
    if (flag) {
        if (a1 >= nums1Size) return nums2[a2];
        else if (a2 >= nums2Size) return nums1[a1];
        else return nums1[a1] > nums2[a2] ? nums2[a2] : nums1[a1];
    }
    
    if (nums1[a1] > nums2[a2]) {
        if (a2 + 1 >= nums2Size) return (nums1[a1] + nums2[a2]) * 1.0 / 2;
        if (nums2[a2 + 1] < nums1[a1]) return (nums2[a2] + nums2[a2 + 1]) * 1.0 / 2;
        return (nums1[a1] + nums2[a2]) * 1.0 / 2;
    } else {
        if (a1 + 1 >= nums1Size) return (nums1[a1] + nums2[a2]) * 1.0 / 2;
        if (nums1[a1 + 1] < nums2[a2]) return (nums1[a1] + nums1[a1 + 1]) * 1.0 / 2;
        return (nums1[a1] + nums2[a2]) * 1.0 / 2;
    }
}

复杂度: 假设两个数组长度为m, n, 由于使用二分查找, 复杂度为O(log(m + n))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值