【笔试练习题】leetcode前100道题里面的hard题解法(更新到第45题)

第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>库中的正则类

代码:</

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值