C/C++教程

Leetcode最长上升子序列LIS

本文主要是介绍Leetcode最长上升子序列LIS,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

理论:动态规划初步--最长上升子序列(LIS)
模板:

void slove()
{
    fill(dp, dp + n, INF);
    for (int i = 0; i < n; i++)
    {
        *lower_bound(dp, dp + n, a[i]) = a[i];
        // *upper_bound(dp, dp + n, a[i]) = a[i];  // 非严格递增用upper_bound
    }
    int first = lower_bound(dp, dp + n, INF) - dp;
    printf("%d\n", dp[first - 1]);
    printf("%d\n", first);
}

LC 1713. 得到子序列的最少操作次数

题解:相当于求最长公共子序列,但是普通的算法需要O(n*m)。
这道题目target数组是互异的,可以给它从1开始编号,拿这个编号规则再给arr编号。这样target已经是升序了,arr的LIS也就是原数组的最长公共子序列。

const int INF = 0x3f3f3f3f;
class Solution {
public:
    int minOperations(vector<int>& target, vector<int>& arr) {
        unordered_map<int, int>mp;
        int cnt = 0;
        for(int num : target) mp[num] = (++cnt);
        vector<int>myarr;
        for(int& num : arr) {
            if(mp[num])  myarr.push_back(mp[num]);
        }
        int n = arr.size();
        vector<int>dp(n, INF);
        for(int num : myarr) {
            *lower_bound(dp.begin(), dp.end(), num) = num;
        }
        int lis = lower_bound(dp.begin(), dp.end(), INF)-dp.begin();
        return target.size() - lis;
    }
};
这篇关于Leetcode最长上升子序列LIS的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!