LeetCode第 646 题:最长对数链(C++)

646. 最长数对链 - 力扣(LeetCode)

这道题的标签虽然是动态规划,但是这是贪心算法的典型区间覆盖类题目:数据结构与算法:37 | 贪心算法:贪心算法实现Huffman压缩编码_zj-CSDN博客

贪心策略如下:每次选择的时候,选左端点跟前面的已经覆盖的区间不重合的(限制条件),右端点又尽量小的。

class Solution {
public:
    int findLongestChain(vector>& pairs) {
        //按右端点进行排序
        sort(pairs.begin(), pairs.end(), [](vector &a, vector &b){return a[1] < b[1];});
        int res = 1;
        vector cur = {pairs[0][0], pairs[0][1]};//用第一个元素初始化
        for(int i = 1; i < pairs.size(); ++i){
            if(pairs[i][0] > cur[1]){
                ++res;
                cur = pairs[i];
            }
        }
        return res;
    }
};

可以使用两个变量记录即可:

class Solution {
public:
    int findLongestChain(vector>& pairs) {
        //按右端点进行排序
        sort(pairs.begin(), pairs.end(), [](vector &a, vector &b){return a[1] < b[1];});
        int res = 1;
       int l = pairs[0][0], r = pairs[0][1];//用第一个元素初始化
        for(int i = 1; i < pairs.size(); ++i){
            if(pairs[i][0] > r){
                ++res;
                l = pairs[i][0];
                r = pairs[i][1];
            }
        }
        return res;
    }
};

其实一个就可以:

class Solution {
public:
    int findLongestChain(vector>& pairs) {
        //按右端点进行排序
        sort(pairs.begin(), pairs.end(), [](vector &a, vector &b){return a[1] < b[1];});
        int res = 1;
        int r = pairs[0][1];//用第一个元素初始化
        for(int i = 1; i < pairs.size(); ++i){
            if(pairs[i][0] > r){
                ++res;
                r = pairs[i][1];
            }
        }
        return res;
    }
};

不过既然标签有dp,那就dp一下吧:

class Solution {
public:
    int findLongestChain(vector>& pairs) {
        sort(pairs.begin(), pairs.end());//这儿会默认对第一个数排序
        //dp[i]表示下标i之前的所有元素有多少能放在它之前
        vector dp(pairs.size(), 1);
       
        for(int i = 1; i < pairs.size(); ++i){
            for(int j = 0; j < i; ++j){//因为是排序过的,所以这儿二分会更快
                if(pairs[j][1] < pairs[i][0])   dp[i] = max(dp[i], dp[j]+1);
            }
        }
        return dp[pairs.size()-1];
    }
};

加上二分(其实这个思路有点像维护单调栈):

class Solution {
public:
    //仿函数,参数一定要加const
    struct cmp1{
        bool operator()(const vector &a, const vector &b){
            return a[1] < b[0];
        }
    };
    //普通bool函数,参数一定要加const
    //这儿还需要加static,或者把函数放在类外
    static bool cmp(const vector &a, const vector &b){
        return a[1] < b[0];
    }
    int findLongestChain(vector>& pairs) {
        //lambda表达式
        sort(pairs.begin(), pairs.end(), [](const auto& a,const auto& b){
            return (a[0]> dp;
        dp.push_back(pairs[0]);
        for(int i = 1; i < pairs.size(); ++i){
            if(pairs[i][0] > dp.back()[1])  dp.push_back(pairs[i]);
            else{
                auto it = lower_bound(dp.begin(), dp.end(), pairs[i], cmp1());
                if(it == dp.end())  continue;
                if((*it)[1] > pairs[i][1])  *it = pairs[i];
            }
        }
        return dp.size();
    }
};

你可能感兴趣的:(leetcode,leetcode)