LeetCode 4. Median of Two Sorted Arrays C++

版权声明:个人整理,仅供参考,请勿转载,如有侵权,请联系[email protected] https://blog.csdn.net/mooe1011/article/details/88288714

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)).

You may assume nums1 and nums2 cannot be both empty.

Example 1:

nums1 = [1, 3]
nums2 = [2]
The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

版本一(自己写的,未经优化):

分别用n-1、m-1代表两个列表的尾,j、k代表两个列表的头。

两个列表先后面向前比较,大的丢掉,即n或者m减一。然后前面向后比较,小的丢掉,即j或者k加一

此时也要考虑n减一和j加一是否重叠,即该数组“去掉”所有数为空了,(m,k同理),然后简化为一列数组,直接用函数找出中位数

再考虑两个数组同时留下一个数的情况

#include<stdio.h>
#include<vector>
using namespace std;

class Solution {
public:
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
		int n = nums1.size(), m = nums2.size();
		int j = 0, k = 0;
		if (n == 0)
			return findMedian(nums2, 0, m - 1);
		else if (m == 0)
			return findMedian(nums1, 0, n - 1);
		while (n + m > 2) {
			if (nums1[n - 1] > nums2[m - 1]) {
				if (n - j - 1 == 0) {
					if (nums2[k] < nums1[n - 1])
						return findMedian(nums2, k + 2, m - 2);
					return findMedian(nums2, k, m - 1);
				}
				n--;
			}
			else {
				if (m - k - 1 == 0) {
					if (nums1[j] < nums2[m - 1])
						return findMedian(nums1, j + 2, n - 2);
					return findMedian(nums1, j, n - 1);
				}
				m--;
			}
			if (nums1[j] <= nums2[k]) {
				j++;
				if (j == n)
					return findMedian(nums2, k, m - 1);
			}
			else {
				k++;
				if (k == m)
					return findMedian(nums1, j, n - 1);
			}
			if (n - j == 1 and m - k == 1) {
				return (nums1[j] + nums2[k]) / 2.0;
			}
		}
		return (nums1[n - 1] + nums2[m - 1]) / 2.0;
	}
	double findMedian(vector<int>& list, int head, int end) {
		if (head == end)
			return list[head];
		int mid = (head + end) / 2;
		int size = end - head + 1;
		if (size % 2 == 0)
			return (list[mid] + list[mid + 1]) / 2.0;
		else
			return list[mid];
	}
};

int main() {
	vector<int> nums1{ 5 };
	vector<int> nums2{ 1,2,3 ,4 };
	printf("%lf", Solution().findMedianSortedArrays(nums1, nums2));
	return 0;
}

版本二(有个实例没通过,待思考):

分别计算两个序列的中位数M1和M2,假设M1>M2,那么数列中比M2大的和比M1小的保留,并且统计去掉“大”(即比M1大)的数的个数和“小”的数的个数,若不相等,个数少的一方需要继续去掉。比如说去掉了3个“大”数,和2个“小”数,那么就需要再去掉一个“小”的数,以达到平衡。

重复上面步骤,直到M1=M2或者只剩下两个数,分别做相应处理即可。

不通过案例[1,2] [-1,3]。它们的中位数是1.5和1,去掉比1小,比1.5大的数,剩下[1] [ ],“大”数去掉了2个,“小”数去掉了1个,需要再去掉一个“小”数,于是剩下[ ] [ ]。出现错误。

可以考虑分情况,如果是序列个数是偶数,则最少保留两个,奇数则最少保留一个,待检验吧

#include<stdio.h>
#include<vector>
#include<math.h>
using namespace std;

class Solution {
public:
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
		int n = nums1.size(), m = nums2.size();
		int h1 = 0, h2 = 0, b1 = n - 1, b2 = m - 1;
		if (n == 0)
			return Median(nums2, h2, b2);
		else if (m == 0)
			return Median(nums1, h1, b1);

		printlist(nums1, h1, b1);
		printlist(nums2, h2, b2);

		while (true) {
			int big = 0, small = 0;
			double m1 = Median(nums1, h1, b1);
			double m2 = Median(nums2, h2, b2);
			printf("\nm1:%f m2:%f\n", m1, m2);

			if (m1 == m2)
				return m1;
			if (m1 > m2) {
				h1 = del(nums1, m2, h1, b1);
				h2 = del(nums2, m2, h2, b2);
				b1 = del(nums1, m1, h1, b1, 1);
				b2 = del(nums2, m1, h2, b2, 1);
			}
			else {
				h1 = del(nums1, m1, h1, b1);
				h2 = del(nums2, m1, h2, b2);
				b1 = del(nums1, m2, h1, b1, 1);
				b2 = del(nums2, m2, h2, b2, 1);
			}
			small = h1 + h2;
			big = n + m - b1 - b2 - 2;
			printf("small: %d,big: %d\n", small, big);
			//printf("h1: %d,b1: %d\n", h1, b1);
			printlist(nums1, h1, b1);
			//printf("h2: %d,b2: %d\n", h2, b2);
			printlist(nums2, h2, b2);
			if (small == big)
				return (nums1[h1] + nums2[h2]) / 2.0;
			else if (small > big) {
				for (int i = small - big; i > 0; i--) {
					if (nums1[b1] > nums2[b2]) {
						if (h1 - b1 == 0)
							return Median(nums2, h2, b2 - i + 1);
						b1--;
					}
					else {
						if (h2 - b2 == 0)
							return Median(nums1, h1, b1 - i + 1);
						b2--;
					}
				}
			}
			else {
				for (int i = big - small; i > 0; i--) {

					if (nums1[h1] > nums2[h2]) {
						if (b2 - h2 == 0)
							return Median(nums1, h1 + i - 1, b1);
						h2++;
					}
					else {
						if (b1 - h1 == 0)
							return Median(nums2, h2 + i - 1, b2);
						h1++;
					}
				}
			}


		}
	}
	double Median(vector<int>& list, int head, int end) {
		if (head == end)
			return list[head];
		int mid = (head + end) / 2;
		int size = end - head + 1;
		if (size % 2 == 0)
			return (list[mid] + list[mid + 1]) / 2.0;
		return list[mid];
	}

	int del(vector<int>& list, double m, int head, int end, int j = 0) {

		int mid = (head + end) / 2;
		printf("list[mid]: %d       m:%f\n", list[mid], m);

		if (j) {
			if (list[mid] < m) {
				while (end >= mid + 1 && list[mid] < m && list[mid + 1] <= m) {
					mid++;
				}
			}
			else if (mid - 1 >= 0)
				mid--;
		}
		else {
			if (list[mid] >= m) {
				while (mid - 1 >= 0 && list[mid] >= m && list[mid - 1] >= m) {
					mid--;
				}
			}
			else if (mid - 1 <= end)
				mid++;
		}
		return mid;
	}

	void printlist(vector<int>& list, int head, int end) {
		printf("head:%d end:%d\nlist:", head, end);
		for (int i = head; i <= end; i++)
			printf("%d ", list[i]);
		printf("\n");
	}
};

int main() {
	vector<int> nums1{ 1,2 };
	vector<int> nums2{ -1,3 };
	printf("%lf", Solution().findMedianSortedArrays(nums1, nums2));
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mooe1011/article/details/88288714
今日推荐