270人阅读 评论(0)

# My O(m+n) Code

class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int totalSize = nums1.size()+nums2.size();
vector<int> nums;

int minNumber;
int i = 0, j = 0;
while (i < nums1.size() && j < nums2.size())
{
minNumber = min(nums1[i], nums2[j]);
//cout << "i: " << i << " j: " << j << endl;
//cout << "minNumber: " << minNumber << endl;
for (; i < nums1.size(); i++)
{
if (nums1[i] == minNumber)
{
//cout << "nums1[" << i << "]: " << nums1[i] << endl;
nums.push_back(nums1[i]);
}
else
{
break;
}
}

for (; j < nums2.size(); j++)
{
if (nums2[j] == minNumber)
{
//cout << "nums2[" << j << "]: " << nums2[j] << endl;
nums.push_back(nums2[j]);
}
else
{
break;
}
}
}

if (i < nums1.size())
for (; i < nums1.size(); i++)
nums.push_back(nums1[i]);

if (j < nums2.size())
for (; j < nums2.size(); j++)
nums.push_back(nums2[j]);

/*
cout << "nums: ";
for (int k = 0; k < totalSize; k++)
cout << nums[k] << " ";
cout << endl;
*/

double median;
if (totalSize % 2 == 1)
median = nums[(totalSize-1)/2];
else
median = 0.5 * (nums[(totalSize-1)/2] + nums[(totalSize-1)/2 + 1]);

return median;
}
};
Runtime: 48 ms

# My O(log(min(m,n))) Code

class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size();
int n = nums2.size();
if (m > n)
return findMedianSortedArrays(nums2, nums1);

int start = 0, end = m;
int i, j;
while (start <= end)
{
i = (start+end)/2;
j = (m+n+1)/2 - i;
cout << "start: " << start << " end: " << end
<< " i: " << i << " j: " << j << endl;

if (i == 0 || j == n || nums1[i - 1] <= nums2[j])
if (j == 0 || i == m || nums1[i] >= nums2[j-1])
break;
else
start = i + 1;
else
end = i - 1;
};

int maxNum;
if (i == 0)
maxNum = nums2[j-1];
else if (j == 0)
maxNum = nums1[i-1];
else
maxNum = max(nums1[i-1], nums2[j-1]);

int minNum;
if (i == m)
minNum = nums2[j];
else if (j == n)
minNum = nums1[i];
else
minNum = min(nums1[i], nums2[j]);

double median;
if (i+j == (m-i)+(n-j))
median = 0.5*(minNum+maxNum);
else
median = maxNum;

return median;
}
};
Runtime: 44 ms

# Explanation of O(log(min(m, n))) Code

Given a sorted array A with length m, we can split it into two part:

{ A[0], A[1], ... , A[i - 1] } | { A[i], A[i + 1], ... , A[m - 1] }


All elements in right part are greater than elements in left part.

The left part has "i" elements, and right part has "m - i" elements.

There are "m + 1" kinds of splits. (i = 0 ~ m)

When i = 0, the left part has "0" elements, right part has "m" elements.

When i = m, the left part has "m" elements, right part has "0" elements.

For array B, we can split it with the same way:

{ B[0], B[1], ... , B[j - 1] } | { B[j], B[j + 1], ... , B[n - 1] }


The left part has "j" elements, and right part has "n - j" elements.

Put A's left part and B's left part into one set. (Let's name this set "LeftPart")

Put A's right part and B's right part into one set. (Let's name this set"RightPart")

            LeftPart           |            RightPart
{ A[0], A[1], ... , A[i - 1] } | { A[i], A[i + 1], ... , A[m - 1] }
{ B[0], B[1], ... , B[j - 1] } | { B[j], B[j + 1], ... , B[n - 1] }


If we can ensure:

 1) LeftPart's length == RightPart's length (or RightPart's length + 1)

2) All elements in RightPart are greater than elements in LeftPart.

Then we split all elements in {A, B} into two parts with eqaul length, and one part is

always greater than the other part. Then the median can be easily found.

To ensure these two condition, we just need to ensure:

 (1) i + j == m - i + n - j (or: m - i + n - j + 1)

if n >= m, we just need to set:

i = 0 ~ m, j = (m + n + 1) / 2 - i

(2) B[j - 1] <= A[i] and A[i - 1] <= B[j]

considering edge values, we need to ensure:

(j == 0 or i == m or B[j - 1] <= A[i]) and

(i == 0 or j == n or A[i - 1] <= B[j])


So, all we need to do is:

 Search i from 0 to m, to find an object "i" to meet condition (1) and (2) above.


And we can do this search by binary search. How?

If B[j0 - 1] > A[i0], then the object "ix" can't be in [0, i0]. Why?

 Because if ix < i0, then jx = (m + n + 1) / 2 - ix > j0,

then B[jx - 1] >= B[j0 - 1] > A[i0] >= A[ix]. This violates

the condition (2). So ix can't be less than i0.


And if A[i0 - 1] > B[j0], then the object "ix" can't be in [i0, m].

So we can do the binary search following steps described below:

1. set imin, imax = 0, m, then start searching in [imin, imax]

2. i = (imin + imax) / 2; j = (m + n + 1) / 2 - i

3. if B[j - 1] > A[i]: continue searching in [i + 1, imax]
elif A[i - 1] > B[j]: continue searching in [imin, i - 1]
else: bingo! this is our object "i"


When the object i is found, the median is:

max(A[i - 1], B[j - 1]) (when m + n is odd)

or (max(A[i - 1], B[j - 1]) + min(A[i], B[j])) / 2 (when m + n is even)
0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：66715次
• 积分：1891
• 等级：
• 排名：千里之外
• 原创：121篇
• 转载：44篇
• 译文：0篇
• 评论：10条
评论排行
最新评论