您的位置:首页 > 编程语言

leetcode题解日练--2016.9.17

2016-09-17 17:37 113 查看

平常心

今日题目:

1、两个有序数组的中位数

2、找到两个数组中最小的k对最小和

今日摘录:

天上浮云如白衣,斯须改变如苍狗。——杜甫《何叹》

4. Median of Two Sorted Arrays | Difficulty: Hard

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

Example 2:

nums1 = [1, 2]

nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

tag:数组|二分|分治

题意:先给定两个数组,求它们的中位数,复杂度O(log (m+n)).

思路:

1、找中位数就是在两个数组中各自找到一个i、j元素作为分割线,分割线需要满足三个方程:

i+j=(nums1.size()+nums2.size()+1)/2 —> 二分去搜索i.j=(nums1.size()+nums2.size()+1)/2-i

nums1[i-1]<=nums2[j] (前提i-1和j不越界)

nums2[j-1]<=nums1[i] (前提j-1和i不越界)

当找到满足条件的i,j时候就返回,

否则如果nums1[i-1]

class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int len1 = nums1.size(),len2 = nums2.size();
if(len1>len2)   return findMedianSortedArrays(nums2,nums1);
int halfLen = (len1+len2+1)/2;
int iLeft = 0,iRight = len1;
double maxLeft = INT_MIN,minRight = INT_MAX;
while(iLeft<=iRight)
{
int i = iLeft+(iRight-iLeft)/2;
int j = halfLen-i;
if(j>0 && i<len1 && nums1[i]<nums2[j-1])
iLeft = i+1;
else if(i>0 && j<len2 && nums2[j]<nums1[i-1])
iRight = i-1;
else
{
if(i==0)
maxLeft = nums2[j-1];
else if(j==0)
maxLeft = nums1[i-1];
else
maxLeft = max(nums1[i-1],nums2[j-1]);
if((len1+len2)%2==1)
return maxLeft;
else if(i==len1)
minRight = nums2[j];
else if (j==len2)
minRight = nums1[i];
else
minRight = min(nums1[i],nums2[j]);
return (maxLeft+minRight)/2;
}
}
return -1;
}
};


结果:29ms

2、一样的思想,转换成找两个数组中的第K大数。

这里偶数个数的情况下要调用两次函数,可以改成加如一个标志位来做。

class Solution {
public:
double findLargestK(const vector<int>&nums1,const vector<int>& nums2,int len1,int len2,int k)
{
int iLeft = 0,iRight = len1;
double res =0;
while(iLeft<=iRight)
{
int i = iLeft+(iRight-iLeft)/2;
int j = k-i;

if(j>len2 ||j>0 && i<len1 && nums1[i]<nums2[j-1])
iLeft = i+1;
else if(i>len1 || i>0 && j<len2 && nums2[j]<nums1[i-1])
iRight = i-1;
else
{
if(i==0)
res = nums2[j-1];
else if(j==0)
res = nums1[i-1];
else
res = max(nums1[i-1],nums2[j-1]);
return res;
}
}
return -1;

}

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {

int len1 = nums1.size(),len2 = nums2.size();
if(len1>len2)   return findMedianSortedArrays(nums2,nums1);

int totalLen = len1+len2;
if(totalLen%2==1)   return findLargestK(nums1,nums2,len1,len2,totalLen/2+1);
else    return (findLargestK(nums1,nums2,len1,len2,totalLen/2)+ findLargestK(nums1,nums2,len1,len2,totalLen/2+1))/2;
}
};


结果:62ms

373. Find K Pairs with Smallest Sums | Difficulty: Medium

You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.

Define a pair (u,v) which consists of one element from the first array and one element from the second array.

Find the k pairs (u1,v1),(u2,v2) …(uk,vk) with the smallest sums.

Example 1:

Given nums1 = [1,7,11], nums2 = [2,4,6], k = 3

Return: [1,2],[1,4],[1,6]

The first 3 pairs are returned from the sequence:

[1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]

Example 2:

Given nums1 = [1,1,2], nums2 = [1,2,3], k = 2

Return: [1,1],[1,1]

The first 2 pairs are returned from the sequence:

[1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]

Example 3:

Given nums1 = [1,2], nums2 = [3], k = 3

Return: [1,3],[2,3]

All possible pairs are returned from the sequence:

[1,3],[2,3]

tag:堆

题意:找到两个数组中最小的k对最小和

思路:

1、建立一个最小堆,这样每次堆顶都是我们需要找的一对数,但是现在不是对一个数字进行排序,而是对一对数字的和进行排序,因此需要自定义一个比较函数,自己定义一个堆处理成对的数据结构。

每次我们取出了(i,j)对元素之后,接下来按理需要放进去(i+1,j)和(i,j+1)。但是在(i+1,j-1)判断的时候同样会加入(i+1,j),这样就重复了。那怎么解决呢?

除了第一行元素加入右边和下面的元素之外,其他元素都只加入下面的元素。

class Solution {
public:
vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
vector<pair<int ,int> > res;
if (nums1.empty() || nums2.empty() || k <= 0)
return res;
//创建一个堆
auto compare = [&nums1,&nums2](pair<int,int> a,pair<int,int>b){
return nums1[a.first]+nums2[a.second] > nums1[b.first]+nums2[b.second];
};
priority_queue< pair<int,int>,vector<pair<int ,int> >, decltype(compare) > heap(compare);
heap.emplace(0,0);
while(k-- && !heap.empty())
{
auto index = heap.top();
heap.pop();
res.emplace_back(nums1[index.first],nums2[index.second]);
if(index.first+1<nums1.size())
heap.emplace(index.first+1,index.second);
if(index.first==0 && index.second+1<nums2.size())
heap.emplace(index.first,index.second+1);
}
return res;
}
};


结果:16ms
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 编程 日记