646 Maximum Length of Pair Chain

本文探讨了在给定的一系列数对中寻找最长数对链的问题,提供了动态规划和贪心算法两种解决方案,并详细解释了每种方法的实现思路及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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:

  1. 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];
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值