在这个问题中,我们需要找到可以形成的最长数对链。数对 (a, b) 的链要求 a < b,并且数对链的连接需要满足 b1 < a2。这类似于寻找最长递增子序列的问题,可以通过动态规划或者贪心算法来解决。
贪心算法通过将数对按右端排序,并逐步选择满足条件的数对,能够在更短的时间内解决问题。本文将详细介绍动态规划和贪心策略,并提供 Python 和 C++ 代码示例,帮助你理解并掌握这一问题的解法。

给定一组数对 pairs,其中每个数对由两个整数组成 (a, b),并且 a < b。一条 数对链 是指可以将数对 (a1, b1) 和 (a2, b2) 连接起来,满足 b1 < a2。你需要找到最长的数对链。
这个问题类似于 最长递增子序列 的问题。我们需要选择数对,并构建满足条件的数对链,使得链的长度最大化。两种解法是常见的:
动态规划:对于每一个数对,检查它之前的所有数对是否满足 b1 < a2,如果满足,则更新当前数对能构成的最长链。
贪心策略:通过对数对的右端 b 进行排序,贪心地选择每一个数对,确保尽可能形成最长的数对链。
a 进行升序排序,或者按照右端 b 进行升序排序。dp[i] 为以第 i 个数对为结尾的最长数对链的长度。pairs[i],遍历之前的所有数对 pairs[j],检查 pairs[j][1] < pairs[i][0],即数对是否可以连接。如果可以,则更新 。
max(dp),即最长数对链的长度。b 进行升序排序。a 大于上一个数对的右端 b,以确保形成最长链。,因为排序需要
的时间,而遍历一遍数对仅需要
的时间。相比之下,动态规划的时间复杂度为
,适合小规模数据。贪心方法在时间效率上更优。
的时间复杂度内解决问题,适用于大规模输入。
以上就是最长数对链问题的基本思路。
class Solution:
def findLongestChain(self, pairs: list[list[int]]) -> int:
# 按照数对的第二个元素(右端点)进行升序排序
pairs.sort(key=lambda x: x[1])
# 初始化计数器和当前数对的结束位置
cur_end = float('-inf')
count = 0
# 遍历每个数对
for pair in pairs:
# 如果当前数对可以与上一个数对连接
if pair[0] > cur_end:
cur_end = pair[1] # 更新结束位置
count += 1 # 更新数对链长度
return countb 进行升序排序,以便我们可以贪心地选择更多的数对。a 是否大于当前链的结束位置 cur_end,如果满足条件,则更新链的结束位置,并增加链的长度。class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
// 按照数对的第二个元素(右端点)进行升序排序
sort(pairs.begin(), pairs.end(), [](vector<int>& a, vector<int>& b) {
return a[1] < b[1];
});
int cur_end = INT_MIN; // 当前数对链的结束位置
int count = 0; // 初始化数对链的长度
// 遍历每个数对
for (const auto& pair : pairs) {
if (pair[0] > cur_end) { // 如果当前数对可以连接
cur_end = pair[1]; // 更新链的结束位置
count++; // 增加链的长度
}
}
return count; // 返回最长数对链的长度
}
};。
的时间内解决问题,是更高效的解法。