zoukankan      html  css  js  c++  java
  • LeetCode #4 中等题(二分,中位数)

    题目: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。

    题解: 一开始没看到要求时间是log(m + n),直接俩下标标记过去了,时间复杂度是 (m + n) / 2。先贴一下这个版本的代码,不过就算这样LeetCode也给过了= =。

    class Solution {
    public:
        double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
            int n = (int)nums1.size(), m = (int)nums2.size();
            int left1 = 0, left2 = 0;
            int numleft1 = 0, numleft2 = 0;
            while (left1 + left2 < (n + m) / 2 + 1){
                numleft1 = numleft2;
                if (left1 == n) numleft2 = nums2[left2++];
                else if (left2 == m) numleft2 = nums1[left1++];
                else {
                    if (nums1[left1] < nums2[left2]) numleft2 = nums1[left1++];
                    else numleft2 = nums2[left2++];
                }
            }
            
            if ((n + m) & 1) return numleft2;
            else return (double)(numleft1 + numleft2) / 2.0;
        }
    };

    接下来是log(n + m) 的代码,思路就是二分,从第一个数组找一个位置 x,第二个数组中找一个位置 y,其中 y = (m + n + 2x) / 2,使得找到的x,y左边的数都大于右边的数即可。

    class Solution {
    public:
        double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
            int m = nums1.size();
            int n = nums2.size();
            if (m == 0) {
                if (n % 2 != 0)
                    return 1.0 * nums2[n / 2];
                return (nums2[n / 2] + nums2[n / 2 - 1]) / 2.0;
            }
            if (n == 0) {
                if (m % 2 != 0)
                    return 1.0 * nums1[m / 2];
                return (nums1[m / 2] + nums1[m / 2 - 1]) / 2.0;
            }
            int total = m + n;
            if ((total & 1) == 1) {
                return find_kth(nums1, 0, nums2, 0, total / 2 + 1);
            }
            return (find_kth(nums1, 0, nums2, 0, total / 2) + find_kth(nums1, 0, nums2, 0, total / 2 + 1)) / 2.0;
    
        }
    
        double find_kth(vector<int>& a, int a_begin, vector<int>& b, int b_begin, int k) {
            if (a_begin >= a.size())
                return b[b_begin + k - 1];
            if (b_begin >= b.size())
                return a[a_begin + k - 1];
            if (k == 1)
                return min(a[a_begin], b[b_begin]);
    
            int mid_a = 0x7fffffff;
            int mid_b = 0x7fffffff;
            if (a_begin + k / 2 - 1 < a.size())
                mid_a = a[a_begin + k / 2 - 1];
            if (b_begin + k / 2 - 1 < b.size())
                mid_b = b[b_begin + k / 2 - 1];
            if (mid_a < mid_b)
                return find_kth(a, a_begin + k / 2, b, b_begin, k - k / 2);
            return find_kth(a, a_begin, b, b_begin + k / 2, k - k / 2);
        }
    };
  • 相关阅读:
    文件下载与中文文件名乱码问题解决
    文件字符编码的转换
    HTML速记
    MySQL学习笔记——安装
    C#防止重复弹出多个窗体
    ASP.NET Gridview中自带的日期格式设置功能
    [转]MSDTC on server '''' is unavailable. 的解决办法
    [转]关于SQL中Between语句查询日期的问题
    [转]SQL触发器实例讲解
    SQL索引技巧_1
  • 原文地址:https://www.cnblogs.com/error408/p/11582116.html
Copyright © 2011-2022 走看看