646. 最长数对链
难度
中等

346

 

 

给出 n 个数对。 在每一个数对中,第一个数字总是比第二个数字小。

现在,我们定义一种跟随关系,当且仅当 b < c 时,数对(c, d) 才可以跟在 (a, b) 后面。我们用这种形式来构造一个数对链。

给定一个数对集合,找出能够形成的最长数对链的长度。你不需要用到所有的数对,你可以以任何顺序选择其中的一些数对来构造。

 

示例:

输入:[[1,2], [2,3], [3,4]]
输出:2
解释:最长的数对链是 [1,2] -> [3,4]
 

提示:

给出数对的个数在 [1, 1000] 范围内。

 

 

思路:

根据题目中所给出的数对链的概念

我们需要选取第二个元素比较小的数对,从而保证后面能选取尽可能多的数对

根据贪心思想我们根据第二个元素从小到大排序,遍历数对容器

从而在上一个数对已经确定的情况下我们选择到第二个元素比较小的,那么我们在选择的时候如何保证

选择的数对的第一个元素比上一个数对的第二个元素大呢?

我们顺着数组向后遍历 所找到的第一个 第一个元素比上一个已经确定的数对的第二个数还要大的就是贪心思想所找到的能让数对链尽可能长的待选择数对

bool cmp(vector<int>& a, vector<int>& b) {
    if (a[1] == b[1]) return a[0] > b[0];
    else return a[1] < b[1];
}
class Solution {
public:
    int findLongestChain(vector<vector<int>>& pairs) {
        //首先如何选择第一个元素
        //数对的第一个数字比第二个数字小 也就是说第一个可以放心地选第二个数字最小的
        //下一个选择的数对应该是 第一个数字比上一个元素的第二个数字大的同时第二个数字比较小
        //也就是在第一个数比上一个数对大的元素中寻找第二个数字比较小的元素
        sort(pairs.begin(), pairs.end(), cmp);
        int res = 1, n = pairs.size();
        int j=0;
        for(int i=1;i<n;i++){
            if(pairs[i][0]>pairs[j][1]){
                res++;
                j=i;
            }
        }
        return res;
    }
};