第4题(2个排序数组的中位数)
找到两个已排序数组的中位数(https://leetcode.com/problems/median-of-two-sorted-arrays/)
解法一:
合并列表,再排序,时间复杂度为O(n+m);
解法二:
① 在nums1和nums2中各找到一个数,保证合并之后的数组中nums1[k_1]与nums2[k_2]相邻,且nums[k_1] < nums[k_2]
int k_1 = nums1.size() / 2;
vector<int>::iterator it2 = upper_bound(nums2.begin(), nums2.end(), nums1[k_1]);
int k_2 = it2 - nums2.begin();
vector<int>::iterator it1 = lower_bound(nums1.begin() + k_1, nums1.end(), nums2[k_2]);
k_1 = it1 - nums1.begin() - 1;
② 递归查找
时间复杂度最好O(log(n + m))(log(n)*log(n+m))
代码:
#include <vector>
#include <iostream>
#include<algorithm>
using namespace std;
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
if (nums1.size() + nums2.size() & 1) { // 是奇数
return findK(nums1, nums2, (nums1.size() + nums2.size()) / 2);
}
else {
double m1 = findK(nums1, nums2, (nums1.size() + nums2.size()) / 2);
double m2 = findK(nums1, nums2, (nums1.size() + nums2.size()) / 2 - 1);
return (m1 + m2) / 2;
}
}
private:
// 找到nums1和nums2合并之后的vector中序号为k的数(序号从0开始)
int findK(vector<int>& nums1, vector<int>& nums2, int k) {
if (nums1.empty()) {
return nums2[k];
}
if (nums2.empty()) {
return nums1[k];
}
int k_1 = nums1.size() / 2;
vector<int>::iterator it2 = upper_bound(nums2.begin(), nums2.end(), nums1[k_1]);
int k_2 = it2 - nums2.begin();
if (k_2 == nums2.size()) {
// nums1[k_1]是分界线,nums2[k_2]是分界线
if (k_1 + k_2 == k) {
return nums1[k_1];
}
else if (k_1 + k_2 > k) {
vector<int> nums1_new(nums1.begin(), nums1.begin() + k_1);
return findK(nums1_new, nums2, k);
}
else {
return nums1[k - k_2];
}
}
// nums1[k_1]是分界线,nums2[k_2]是分界线,排序之后的数组:nums1[k_1]与nums2[k_2]相邻,且nums1[k_1]更小
vector<int>::iterator it1 = lower_bound(nums1.begin() + k_1, nums1.end(), nums2[k_2]);
k_1 = it1 - nums1.begin() - 1;
if (k_1 + k_2 + 1 == k) {
return nums2[k_2];
}
else if (k_1 + k_2 == k) {
return nums1[k_1];
}
else if (k_1 + k_2 + 1 > k) {
vector<int> nums1_new(nums1.begin(), nums1.begin() + k_1);
vector<int> nums2_new(nums2.begin(), nums2.begin() + k_2);
return findK(nums1_new, nums2_new, k);
}
else {
vector<int> nums1_new(nums1.begin() + k_1 + 1, nums1.end());
vector<int> nums2_new(nums2.begin() + k_2 + 1, nums2.end());
return findK(nums1_new, nums2_new, k - (k_1 + k_2 + 2));
}
}
};
代码实测在leetcode上跑出来解法二并没有比解法一快。
解法三:
推荐解法,代码是一个博客里的:https://segmentfault.com/a/1190000015034975?utm_source=tag-newest
代码:
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size();
int n = nums2.size();
int l = (m + n + 1) >> 1;
int r = (m + n + 2) >> 1;
int* ln = m > 0 ? &nums1[0] : nullptr;
int* rn = n > 0 ? &nums2[0] : nullptr;
return ( getKth(ln, m, rn, n, l) + getKth(ln, m, rn, n, r) ) / 2.0;
}
int getKth(int* ln, int m, int* rn, int n, int k) {
if (m > n) {
return getKth(rn, n, ln, m, k);
}
if (m == 0) {
return rn[k - 1];
}
if (k == 1) {
return min(ln[0], rn[0]);
}
int i = min(m, k / 2), j = min(n, k / 2);
if (ln[i - 1] > rn [j - 1]) {
return getKth(ln, m, rn + j, n - j, k - j);
} else {
return getKth(ln + i, m - i, rn, n, k - i);
}
}
};
第10题(正则表达式)
正则匹配(https://leetcode.com/problems/regular-expression-matching/)
方法一:使用C++<regix>库中的正则类
代码:</