Leetcode 动态规划解决字串与子序列问题

利用动态规划解决字串子序列问题

动态规划?

通过总结规律找出最优解决方案(数学归纳法)!!!
动态规划一般可分为线性动规,区域动规,树形动规,背包动规四类

子串和子序列的区别?

1.子串是字符串连续不断的一块字符串:例如"abcdefg" 则"bcd" 为其子串;
2.子序列中的字符都是字符串的子集,但是一定是顺序上是单调的:例如"abcdefg" 则"acfg"其子序列;

最长递增子串与最长递增子序列

最长递增子序列(Longest Increasing Subsequence,简写 LIS)是比较经典的一个问题,比较容易想到的是动态规划解法,时间复杂度 O(N^2),我们借这个问题来由浅入深讲解如何写动态规划。比较难想到的是利用二分查找,时间复杂度是 O(NlogN),
在这述
动态规划:DP[i] = fmax(RES, DP[i - 1] + 1)

在这里图片描述
C++:

int longestSubString(std::vector<int> s)
{
   
   
	std::vector<int> dp(s.size(), 0);
	dp[0] = 1;
	for (int i = 1; i < s.size(); ++i)
	{
   
   
		for(int j = 0; j < i; j++)
		{
   
   
			if(s[i] > s[j])
				dp[i] = fmax(dp[i], dp[j] + 1);
		}
	}

	return *max_element(dp.begin(), dp.end());
}

最长递增子串
解题思路:dp[i]:表示第i个元素,它的递增元素的个数。比如[1,3,5 ]元素3 从1递增到3 递增元素个数是2,dp[1]=2, dp=[1]*n

   int findLengthOfLCIS(vector<int>& nums) {
   
   
        int length = nums.size();
        if(!length)
            return 0;
        vector<int> dp(length, 1);
        int res = 1;
        for(int i = 1; i < length; i++)
        {
   
   
            if(nums[i - 1] < nums[i])
                dp[i] = dp[i - 1] + 1;
            res = fmax(dp[i], res);
        }
        return res;
    }

(2)滑动窗口
算法:

每个(连续)增加的子序列是不相交的,并且每当 nums[i-1]>=nums[i] 时,每个此类子序列的边界都会出现。当它这样做时,它标志着在 nums[i] 处开始一个新的递增子序列,我们将这样的 i 存储在变量 anchor 中。
例如,如果 nums=[7,8,9,1,2,3],那么 anchor 从 0 开始(nums[anchor]=7),并再次设置为 anchor=3(nums[anchor]=1)。无论 anchor 的值如何,我们都会记录 i-anchor+1 的候选答案、子数组 nums[anchor]、nums[anchor+1]、…、nums[i] 的长度,并且我们的答案会得到适当的更新。

  int findLengthOfLCIS(vector<int>& nums) {
   
   
        int pos = 0, res = 0;
        int length = nums.size();
        for(int i = 0; i < length; i++)
        {
   
   
            if(i > 0 && nums[i - 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值