LintCode 1443. 最长AB子串

在这里插入图片描述

新路历程:

一开始想到了用暴力循环去做,但是不用想也知道肯定会超时。
当暴力超时时,优化思路一般两个:双指针 or 动态规划。这道题看不出来有明显的双指针思路,于是转而思考如何用DP做这道题。思考DP函数的输入大概是i, j,表示[i, j]区间内的最长字串的长度,感觉返回应该是max(dfs(i-1, j) +1, dfs(i-1, j-1) + 2, …)大概这种样子。

结果写一半发现不对,递归的本质在于原问题转化为下一层级的子问题,因此需要思考原问题的解与子问题的解有什么关系?这道题假设[i,j]区间内的最长满足要求的子串长为k, 那么[i+1, j-1]内的最长字串与其有什么关系呢?

[i+1, j-1]内的最长子串既可以与[i, j]的结果相关,也可以不相关。1、假设相关,那么i, j至少有一个元素落入了最长字串的统计中,此时a.可能i落入,dfs(i,j) = dfs(i, j-1),b.可能j落入,dfs(i,j) = dfs(i-1, j),c.也可能i,j全都落入, dfs(i,j)=dfs(i-1,j-1) + 2 ;此时又得分情况如果统计了两个A,那么后面判断A-2与B的数量,此时想到这里发现已经破坏递归中‘循环不变量’的性质了,因为这一层判断A B相等,但下一层判断A比B是不是少两个,这个时候又想到在函数里再传一个参数表示A与B的差值,越想越乱。。。2、假设不相关,那么dfs(i,j) = dfs(i+1, j-1)。

或者说这道题没办法用DP解决的难点在于无法确定当前层的答案与下一层的答案的相关性?这个点还需要进一步考虑。不管这道题能不能用DP想到这都很复杂了。

注意的点:

1、前缀初始化第一个前缀和的值(i=0)
2、前缀和这种操作可以很好地解决数量统计类的题目(AB串,1111方形矩阵)

解法:一维数组前缀和

class Solution:
    """
    @param s: a String consists of a and b
    @return: the longest of the longest string that meets the condition
    """
    def get_ans(self, s: str) -> int:
        # 一维数组的前缀和
        presum = 0
        hist = {0: -1}
        max_len = 0
        for i in range(len(s)):
            if s[i] == 'A': v = 1
            else: v = -1
            presum += v
            if presum in hist.keys():
                l1 = i - hist[presum]
                max_len = max(max_len, l1)
            else:
                hist[presum] = i
        return max_len
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值