zoukankan      html  css  js  c++  java
  • LeetCode.4 两个有序数组的中位数问题

    这道题是那种典型的有显而易见的解法, 但是想要达到较优的时间复杂度的话就不是这么好做的题目.

    我来说说我自己的思考过程 :

    1. 首先最先想到的是 O(m + n) 的解法, 也就是利用归并排序的归并将两个数组合成一个.
    2. 然后题目中要求的时间复杂度是 O(log (m + n)), 想到log自然就想到了分制之类的东西, 也就是通过用常数级别的操作来减小问题规模来求解.
    3. 其实算法导论里面有类似的题目, 当时觉得简单就没有实现, 基本思路是 : 尝试着通过不断地比较两个数组的中值来舍弃掉一些元素(就是说我们可以判断出整体中值一定是会出现在两个中值之间的, 包括边界). 于是我开始依照这种思路来进行代码的实现.

    然后我碰到了如下问题 :
    1. 没有考虑一开始输出的两个数组都为空的corner case.
    2. 舍弃一部分元素时将中值舍去, 其实整体中值极有可能是两个中值求平均数, 也就是我上面提到的整体中值极有可能出现在两个中值之间.
    3. 当较小的数组下降到2的时候, 此时必须开始求解, 因为无法舍弃更多的元素.(但是事实上, 这时候开始求解, 如果使用不插入的话, 其实情况很多, 讨论起来特别费劲)

    经过了一天的尝试, 最后我放弃了这种做法. 我开始在网上寻找新的解法, 最后我觉得最好的解法是 : LeetCode 笔记系列一 Median of Two Sorted Arrays.

    不过他上面的代码并不符合leetcode上提供的接口, 所以我自己给出了以下实现 :

    #include <vector>
    using namespace std;
    
    class Solution {
    public:
        double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
            auto size = nums1.size() + nums2.size();
            if(size % 2 == 0){
                return (findKth(nums1.cbegin(), nums1.cend(), nums2.cbegin(), nums2.cend(), size / 2 + 1)
                        + findKth(nums1.cbegin(), nums1.cend(), nums2.cbegin(), nums2.cend(), size / 2)) / 2;
            }else{
                return findKth(nums1.cbegin(), nums1.cend(), nums2.cbegin(), nums2.cend(), size / 2 + 1);
            }
        }
    
    private:
        double findKth(vector<int>::const_iterator n1Start, vector<int>::const_iterator n1End,
                       vector<int>::const_iterator n2Start, vector<int>::const_iterator n2End,
                       long k){
            // make sure size1 >= size2
            auto size1 = n1End - n1Start;
            auto size2 = n2End - n2Start;
            if(size1 < size2)   return findKth(n2Start, n2End, n1Start, n1End, k);
    
            if(size1 == 0)  return 0;
            if(size2 == 0)  return n1Start[k - 1];
            if(k == 1)  return std::min(n1Start[0], n2Start[0]);
    
            long p2 = std::min(size2, k / 2);
            long p1 = k - p2;
            if(n1Start[p1 - 1] >= n2Start[p2 - 1]){
                k = p1;
                n2Start += p2;
            } else{
                k = p2;
                n1Start += p1;
            }
            return findKth(n1Start, n1End, n2Start, n2End, k);
        }
    
    };
    
  • 相关阅读:
    正当防卫与互殴的界限在哪里
    [php入门] 5、初学CSS从中记下的一些基础点(For小白)
    [ZigBee] 13、ZigBee基础阶段性回顾与加深理解——用定时器1产生PWM来控制LED亮度(七色灯)
    [ZigBee] 12、ZigBee之看门狗定时器——饿了就咬人的GOOD DOG
    [ZigBee] 11、ZigBee之睡眠定时器二
    [ZigBee] 10、ZigBee之睡眠定时器
    [ZigBee] 9、ZigBee之AD剖析——AD采集CC2530温度串口显示
    [ZigBee] 8、ZigBee之UART剖析·二(串口收发)
    [php入门] 4、HTML基础入门一篇概览
    [ZigBee] 2、 ZigBee开发环境搭建
  • 原文地址:https://www.cnblogs.com/nzhl/p/6068016.html
Copyright © 2011-2022 走看看