leetcode__单词拆分II__python

博客围绕类似单词拆分I的题目展开,解题思路是用深度优先搜索返回每种切分结果。改进思路为反向判断字符位置到最终位置子串是否可分并保存bool数组,再正向dfs,利用反向信息避免不必要计算,改进后时间复杂度大幅提升。

解题思路:

这道题一眼看去,就死类似于单词拆分I的深度优先搜索就可以解决的题目,不过这里升级了,就是要把每一种切分结果都要返回。
具体代码如下:

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
        mem = {}
        tmp = self.dfs(s, wordDict, mem)
        res = []
        for item in tmp:
            res.append(' '.join(item))
        return res
    
    def dfs(self, s, wordDict, mem):
        if self.check(s, wordDict) == False:
            return []
        if s in mem.keys():
            return mem[s]
        if s == '':
            return [[]]
        res = []
        for i in range(1, len(s) + 1):
            if s[:i] in wordDict and self.check(s[i:], wordDict):
                substr = self.dfs(s[i:], wordDict, mem)
                for item in substr:
                    res.append([s[:i]] + item)
        return res

    def check(self, s, wordDict):
        if s in wordDict:
            return True
        index_set = [False]*(len(s) + 1)
        index_set[0] = True
        for i in range(1, len(s) + 1):       #   i    [1, 8]
            for idx in range(i):             #   idx  [0, 7]
                if index_set[i] == False and index_set[idx] and s[idx:i] in wordDict:
                    index_set[i] = True
        return index_set[-1]

改进思路:

1.反向判断,判断每一个字符的位置到最终的位置之间的子串是否可分,判断完之后将这个bool数组保存起来;
2.正向dfs,利用反向判断的信息可以快速判断后面是否可以分解,从而避免不必要的计算量;
具体代码如下:

class Solution:
    '''反向判断'''
    def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
        judges = self.get_judgement(s, wordDict)
        if judges[0] == False:
            return []
        mem = {}
        res = []
        tmp = self.dfs(s, wordDict, mem, judges)
        for item in tmp:
            res.append(' '.join(item))
        return res

    def dfs(self, s, wordDict, mem, judges):
        if s in mem.keys():
            return mem[s]
        if s == '':
            return [[]]
        res = []
        for i in range(1, len(s)+1):
            #先判断字典中是不是存在这个字符串,然后判断这个字符串后面是否能分解
            if s[:i] in wordDict and judges[i]:
                substr = self.dfs(s[i:], wordDict, mem, judges[i:])
                for item in substr:
                    res.append([s[:i]] + item)
        mem[s] = res
        return res

    def get_judgement(self, s, wordDict):    #len(s) = 5
        res = [False] * (len(s) + 1)
        res = [False] * (len(s) + 1)     
        res[-1] = True
        for i in range(len(s))[::-1]:   #i   7 to 0  
            for ptr in range(i+1, len(s)+1)[::-1]:    #ptr 8 to i+1 
                if res[i] == False and res[ptr] and s[i:ptr] in wordDict:
                    res[i] = True
        return res

经过改进之后,时间复杂度得到了很大的提升,可以提交观察结果查看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值