Leetcode 题解系列(三)
来源:互联网 发布:云服务器软件 编辑:程序博客网 时间:2024/05/24 07:28
Median of Two Sorted Arrays
题目要求/There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).Example 1:nums1 = [1, 3]nums2 = [2]The median is 2.0Example 2:nums1 = [1, 2]nums2 = [3, 4]The median is (2 + 3)/2 = 2.5
题目分析
1. 暴力解法
直接将两个数组一起排序,在求中位数。时间复杂度
2. 归并法
利用归并排序的思想,对两个数组进行归并。归并不用完全做完,只需完成一半即可求得中位数。时间复杂度
3. 分割
思考:中位数既是将数组分为两半,那么只要找到一个点,可以将数组分为两个部分就好。
对于一个合乎条件的分割点,有:
+ 分割一个数组后,前一个数比另一个数组分割完后后面一个数大
+ 分割一个数组后,后一个数比另一个数组分割完后前面一个数
1. 采用朴素的移动法
每次检查分割是否符合条件,不是则向对应方向移动。代码如下
class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { auto len1 = nums1.size(), len2 = nums2.size(); if (len1 == 0) { return getMedian(nums2); } if (len2 == 0) { return getMedian(nums1); } auto half = (len1 + len2 + 1) / 2; auto sep1 = len1 / 2, sep2 = half - sep1; std::pair<long, long> p1, p2; for (;;) { p1 = separate(nums1, sep1), p2 = separate(nums2, sep2); if (p1.first <= p2.second && p2.first <= p1.second) { break; } else if (p1.first > p2.second) { sep1--; sep2++; } else { sep1++; sep2--; } } long mids[4] = {p1.first, p1.second, p2.first, p2.second}; std::sort(mids, mids + 4); if ((len1 + len2) % 2 == 0) { return (static_cast<double>(mids[1]) + static_cast<double>(mids[2])) / 2; } return static_cast<double>(mids[1]); } std::pair<long, long> separate(std::vector<int>& nums, int pos) { long left = std::numeric_limits<long>::min(), right = std::numeric_limits<long>::max(); if (pos > 0 && pos <= nums.size()) { left = nums[pos - 1]; } if (pos >= 0 && pos < nums.size()) { right = nums[pos]; } return std::make_pair(left, right); } double getMedian(std::vector<int> nums) { auto len = nums.size(); if (len == 0) { return 0; } else if (len % 2 == 0) { return (static_cast<double>(nums[len / 2]) + static_cast<double>(nums[len / 2 - 1])) / 2; } return static_cast<double>(nums[len / 2]); }};
2. 使用二分的方法
class Solution2 { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { auto len1 = nums1.size(), len2 = nums2.size(); if (len1 > len2) { return findImpl(nums2, nums1); } return findImpl(nums1, nums2); } double findImpl(vector<int>& nums1, vector<int>& nums2) { auto len1 = nums1.size(), len2 = nums2.size(); if (len1 == 0) { return getMedian(nums2); } long long half = (len1 + len2 + 1) / 2; long long up_bound = len1 + 1, low_bound = -1; long long sep1 = (up_bound + low_bound + 1) / 2, sep2 = half - sep1; std::pair<long, long> p1, p2; for (;;) { p1 = separate(nums1, sep1), p2 = separate(nums2, sep2); if (p1.first <= p2.second && p2.first <= p1.second) { break; } else if (p1.first > p2.second) { up_bound = sep1; } else { low_bound = sep1; } sep1 = (up_bound + low_bound + 1) / 2; sep2 = half - sep1; } long mids[4] = {p1.first, p1.second, p2.first, p2.second}; std::sort(mids, mids + 4); if ((len1 + len2) % 2 == 0) { return (static_cast<double>(mids[1]) + static_cast<double>(mids[2])) / 2; } return static_cast<double>(mids[1]); } std::pair<long, long> separate(std::vector<int>& nums, long long pos) { long left = std::numeric_limits<long>::min(), right = std::numeric_limits<long>::max(); if (pos > 0 && pos <= nums.size()) { left = nums[pos - 1]; } if (pos >= 0 && pos < nums.size()) { right = nums[pos]; } return std::make_pair(left, right); } double getMedian(std::vector<int> nums) { auto len = nums.size(); if (len == 0) { return 0; } else if (len % 2 == 0) { return (static_cast<double>(nums[len / 2]) + static_cast<double>(nums[len / 2 - 1])) / 2; } return static_cast<double>(nums[len / 2]); }};
二分的方法理论上时间复杂度应该小于第一种,但是实际上leetcode的运行时间反而更慢了,可能是测试样例中,中位数均比较居中的缘故。
阅读全文
0 0
- Leetcode 题解系列(三)
- Leetcode 题解系列(一)
- Leetcode 题解系列(二)
- Leetcode 题解系列(四)
- Leetcode 题解系列(五)
- Leetcode 题解系列(六)
- Leetcode 题解系列(七)
- Leetcode 题解系列(八)
- Leetcode 题解系列(九)
- Leetcode 题解系列(十)
- Leetcode 题解系列(十一)
- Leetcode 题解系列(十三)
- Leetcode 题解系列(十二)
- LeetCode OJ题解系列
- LeetCode题解(三)
- LeetCode Single Number系列题解
- LeetCode题解系列--1. Two Sum
- LeetCode题解系列--5. Longest Palindromic Substring
- Netty源码分析:客户端连接
- java开发之验证码
- C+++string类如何判断字符串为空
- 图片上增加水印文字
- 51Nod-1315 合法整数集
- Leetcode 题解系列(三)
- VS2010生成动态库相关问题
- ScrollView嵌套WebView报Unable to create layer for WebView
- ECMAScript-单体内置对象
- Json工具类--使用json-lib实现json的序列化和反序列化
- MyBatis之使用resultMap实现高级映射
- centos7安装git
- Tomcat源码分析--MessageBytes类
- springmvc学习笔记(1)-框架原理和入门配置