leetcode之Word Break

原题如下:

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = "leetcode",
dict = ["leet", "code"].

Return true because "leetcode" can be segmented as "leet code".

此题有点儿难度,但其实应该是能够想起用递归求解的,即针对遍历的每个位置将字符串分为两部分,若前一部分在字典中,则只需递归求解剩余子串是否在字典中,这里需要注意的是递归返回true值的条件。这种方法很明显存在很多冗余的比较。

bool wordBreak(string s, unordered_set<string> &dict) {
		bool b = false;
		for(int i = 1; i <= s.size(); i++){
			string str = s.substr(0,i);
			if(dict.find(str) != dict.end()){
				if(i == s.size())
					return true;
				string subStr =  s.substr(i);
				b = wordBreak(subStr,dict);		
				if(b)
				return true;
	 	    }
		}			
		return false;
	}
在上题的基础上可以采用动态规划的方法来减少冗余的比较,其思路是:长度为len的字符串共有len + 1 种分割方法将其分为两部分,所以可以创建一个len + 1 大小的bool向量bv来存储字典中是否包含以当前分割的左半部分的字符串,首先赋初值bv[0] = true;然后依次遍历求解后边的分割方法,针对每次分割的左半部分,再次遍历分割的左半部分,这样在判断时可以在之前以求解的基础上进行简化,当发现存在组合时即可提前结束遍历。最终bv[len]即为所求。

bool wordBreak(string s, unordered_set<string> &dict) {
		vector<bool>bv(s.size() + 1,false);
		bv[0] = true;
		for(int i = 1;i <= s.size(); i++){
			for(int j = 0; j < i; j++){
				if(bv[j] == true && dict.find(s.substr(j,i - j)) != dict.end())
				{
				    bv[i] = true;
					break;
				}
			}
		}
		return bv[s.size()];
    }

这道题虽然有难度,但其求解思路和优化方法是逐步深入和有迹可循的,还是要加强练习、记忆、和总结才行。

补:

    按照第二种思路Python实现如下:

class Solution:
    # @param s, a string
    # @param dict, a set of string
    # @return a boolean
    def wordBreak(self, s, dict):
        L = []
        for i in range(len(s)):
            L.append(False)
        L.append(False)
        L[0] = True
        for i in range(len(s)) :
            for j in range(len(L)):
                str = s[j:i + 1]
                if L[j] == True  and  str in dict:
                    L[i + 1] = True
                    break
        return L[-1]
在leetcode上实现的第一个Python代码哦,纪念一下~



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值