您的位置:首页 > 其它

经典算法 | 给定n个集合,求解一个范围,使得这个范围包含每个集合至少m个数

2018-01-18 17:51 316 查看
这题给你许多个数组,让你给出一个范围,这个范围里面包含每个数组至少一个数,并且使这个范围尽可能的小。
使得这个范围里面包含每个数组至少m个数也可以适用相同的方法解决,只需要修改一个值就行了。
这题是使用贪心算法的思想解决的。
首先把所有数组里面的值都混合在一起,组成一个数组theMark,然后排序,混合之后的数组为pair类型的数组,pair第一个值表示得到的这个值属于几号数组,第二个值才真正表示假如混合数组的这个数的值
使用两个值left和right,isGet[i]用来记录left和right之间的所有数包含了i号数组里面多少个值,使用k表示left和right之间包含了多少个区间,
设区间总数为n
算法首先right不断向右,直到找到第一个left和right区间使得left和right之间包含了所有区间至少一个值,然后left不断向右,直到left在向右一格k将小于n,这个时候left和right之间的范围就是theMark[0]到theMark[right]之间所有可能包含n个组的范围里面最小的一个,这个时候theMark[0]到theMark[right]之间包含全部n个组的最小范围就得到了,right记录的是这个组的右端,left记录的是最后一个加以判定的组的左端,
   Left往右一步然后right继续往右,当left到right之间k不为n的时候,这个时候theMark[0]到theMark[right]之间不会得到比之前得到的范围(也就是前一个left到right这个范围)更好的范围,维持现状不变,这个时候theMark[0]到theMark[right]包含全部n个组的最小范围处于得到状态,left记录的是最后一个加以判定的组的左端,因此right继续往右
  当left到right之间的k为n的时候,left和right之间可能得到一个右端为right的比之前的所有范围都要好的范围,因此left不断往右,直到下一步k<n,比较这个范围是否有已经有的最好范围要好,判定完成之后这个时候theMark[0]到theMark[right]包含全部n个组的最小范围处于得到状态,left记录的是最后一个加以判定的组的左端,right继续往右
  直到right等于数组的最右端,这个时候theMark数组里面全部的数字中包含全部n个组的最小范围处于得到状态,left记录的是最后一个加以判定的组的左端,这个时候被记录的组就是最小的范围
  本题的思路还适用求一个集合,使得这个集合包含每个集合至少一个数,使得集合里面的数最少,或者是求一个范围,使得这个范围包含每个集合至少一个数,使得这个范围里面的数最少class Solution {
public:
static bool cmp(pair<int, int> & a, pair<int, int> &b)
{
return a.second < b.second;
}

vector<int> smallestRange(vector<vector<int>>& nums) {
vector<pair<int, int>> theMark;
int theAllG = nums.size();
vector<int> isGet(nums.size(), 0);
for(int i=0;i<nums.size();i++)
for (int j = 0; j < nums[i].size(); j++)
{
theMark.push_back(pair<int, int>(i, nums[i][j]));
}
sort(theMark.begin(), theMark.end(), cmp);
int left, right,k;
int n = theMark.size();
left = 0; right = 0; k = 0;
vector<int> result; int theMinLength=1000000;
while (right != n)
{
if (isGet[theMark[right].first] == 0)
{
k++;
}
isGet[theMark[right].first]++;
if (k == theAllG)
{
while (k == theAllG)
{
if(isGet[theMark[left].first]==1)
{
k--;
}
isGet[theMark[left].first]--;
left++;
}
int a, b;
a = theMark[left - 1].second; b = theMark[right].second;
if (b - a < theMinLength)
{
theMinLength = b - a;
result.clear();
result.push_back(a); result.push_back(b);
}
}
right++;
}
return result;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  贪心算法
相关文章推荐