天天刷leetcode——动态规划(子串们的故事)

647. 回文子串

解题思路

1. 暴力求解

    def countSubstrings(self, s: str) -> int:
        res = 0
        def cal(s):
            if s[::-1] == s:
                return 1
            else:
                return 0
        for i in range(len(s)):
            for j in range(i,len(s)):
                target = s[i:j+1]
                res += cal(target)
        return res

时间复杂度 O ( n 3 ) O(n^3) On3真高呀
在这里插入图片描述

2. 动态规划

d p [ i ] [ j ] dp[i][j] dp[i][j] 表示字符串 s [ i , j ] s[i,j] s[i,j]是否是回文子串。 j < = i j<=i j<=i,求回文子串数量也就是,也就是求对角线上面1的数量。
状态转移:

  • 如果 s [ i ] = = s [ j ] s[i] == s[j] s[i]==s[j] i − j < 2 i - j < 2 ij<2 或者 s [ i ] = = s [ j ] s[i] == s[j] s[i]==s[j] d p [ j + 1 ] [ i − 1 ] dp[j + 1][i - 1] dp[j+1][i1] d p [ j ] [ i ] = 1 dp[j][i] = 1 dp[j][i]=1
  • 由多于 2 个字符组成,首尾字符相同,且剩余子串是一个回文串
    def countSubstrings(self, s: str) -> int:
            res = 0
            n = len(s)
            dp = [[0] * n for _ in range(n)]
            for i in range(n):
                for j in range(i + 1):
                    if s[i] == s[j] and (i - j < 2 or dp[j + 1][i - 1]):
                        dp[j][i] = 1
                        res += 1
            return res

时间复杂度 O ( n 2 ) O(n^2) O(n2)
在这里插入图片描述

3. 中心扩展

找到子串的中心,使用两个指针不断向两端延伸。需要注意的是,如果是奇数,中心只有一个。如果是偶数回文中心有两个。

def count(s):
	n = len(s)
	res = 0
	def help(i,j):
		while i >= 0 and j < n and s[i] == s[j]:
			i -= 1
			j += 1
			res += 1
	for i in range(n):
		help(i,i)
		help(i,i+1)
	return res

空间复杂度O(1)
在这里插入图片描述

674. 最长连续递增序列

题目描述

给定一个未经排序的整数数组,找到最长且连续的的递增序列,并返回该序列的长度。

解题思路

1. 动态规划

状态:dp[i] 表示nums[i]即为的序列最长连续递增序列的长度
状态转移:1. 如果 n u m s [ i + 1 ] > n u m s [ i ] nums[i+1]>nums[i] nums[i+1]>nums[i], dp[i+1] = dp[i]+1
2.如果nums[i+1]<nums[i]$, dp[i+1] =1

        if len(nums)<1:
            return 0
        dp = [1 for i in range(len(nums))]
        for i in range(1,len(nums)):
            if nums[i] > nums[i-1]:
                dp[i] = dp[i-1]+1
            else:
                dp[i] = 1
        return max(dp)

5. 最长回文子串

和子串和那题相似。

    def longestPalindrome(self, s: str) -> str:
        # dp[i][j] 表示是否是回文子串
        if len(s) < 1:
            return ''
        result = []
        dp = [[0] * len(s) for _ in range(len(s))]
        for i in range(len(s)):
            for j in range(i+1):
                if (s[i] == s[j] and i -j < 2) or (s[i] == s[j] and dp[j+1][i-1]==1):
                    dp[j][i] = 1
                    result = s[j:i+1] if len(s[j:i+1]) > len(result) else result
        return result

leetcode 516. 最长回文子序列

给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。可以假设 s 的最大长度为 1000 。
注意:回文子序列判断的过程可以删除一个元素
待补充

reference

[1] 647. 回文子串https://leetcode-cn.com/problems/palindromic-substrings/submissions/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值