1 题目
You are given n
pairs of numbers. In every pair, the first number is always smaller than the second number.
Now, we define a pair (c, d)
can follow another pair (a, b)
if and only if b < c
. Chain of pairs can be formed in this fashion.
Given a set of pairs, find the length longest chain which can be formed. You needn't use up all the given pairs. You can select pairs in any order.
Example 1:
Input: [[1,2], [2,3], [3,4]]
Output: 2
Explanation: The longest chain is [1,2] -> [3,4]
Note:
- The number of given pairs will be in the range [1, 1000].
2 尝试解
2.1 分析
首先用动态规划方法,将数对以开始时间排列,F(n)表示以第n个数对结尾最长数对链的长度。则F(n) = 1 + max(F(k) for pair[k].second < pair[n].second)。即在所有可以与第n个数对构成链的数对集中遍历,取最大值即可。
再考虑贪心算法,每次取最早结束或最晚开始数对,且不与上一个取的数对构成矛盾。即每次取占用资源最少的数对。参考算法导论活动选择问题。
2.2 代码
动态规划:
class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
sort(pairs.begin(),pairs.end());
vector<int> saver(pairs.size(),1);
int result = 0;
for(int i = 1; i < saver.size(); i++){
int before_max = 0;
for(int j = i-1; j >=0 ; j--){
if(pairs[j][1] < pairs[i][0])
before_max = max(before_max,saver[j]);
}
saver[i] += before_max;
result = max(result,saver[i]);
}
return result;
}
};
贪心算法:
class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
sort(pairs.begin(),pairs.end());
int result = 0;
int last_start = INT_MAX;
while(pairs.size()){
if(pairs.back()[1] < last_start){
result += 1;
last_start = pairs.back()[0];
}
pairs.pop_back();
}
return result;
}
};
3 标准解
class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
sort(pairs.begin(), pairs.end(), cmp);
int cnt = 0;
for (int i = 0, j = 0; j < pairs.size(); j++) {
if (j == 0 || pairs[i][1] < pairs[j][0]) {
cnt++;
i = j;
}
}
return cnt;
}
private:
static bool cmp(vector<int>& a, vector<int>&b) {
return a[1] < b[1];
}
};