[LeetCode] Word Break

本文详细介绍了如何使用字典匹配算法实现字符串的分割,包括递归与迭代两种方法,以及通过设置辅助数据结构优化性能。通过实例分析,阐述了算法的核心思想与应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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".

对原题的完全理解是由于有几个case没过,这里提供一下帮助理解题意。

Input:	"bb", ["a","b","bbb","bbbb"]
Output:	false
Expected:	true
Input:	"abcd", ["a","abc","b","cd"]
Output:	false
Expected:	true

对s中当前尚未匹配的第一个字母,在vdict中逐个单词对比,看是否可以匹配,匹配成功则保存此字母的index以及单词的指针itr(通过栈保存);如果遍历vdict所有单词后都未匹配成功,说明上一个匹配成功的单词不合适,需要退栈,弹出上一次匹配成功的单词和index,对此index重新匹配其他单词。AC代码:


class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
    	vector<string> vdict;//set转换为vector做一个排序
    	for (unordered_set<string>::iterator vitr = dict.begin(); vitr!=dict.end(); vitr++)vdict.push_back(*vitr);
    	sort(vdict.begin(), vdict.end());
    
    	vector<int> iIndex;//用于记忆分割成word在s中的首字母位置
    	vector<vector<string>::iterator > iSet;//用于记忆上一次查找到的vdict位置
    
    	int i = 0;
    	bool popfg = false;
    	while (i < s.size())
    	{
    		vector<string>::iterator itr = vdict.begin();
    		if (popfg)
    		{
    			itr = iSet.back()+1;
    			if (itr == vdict.end())return false;
    			iSet.pop_back();
    			popfg = false;
    		}//itr默认从头开始,如果上轮有退栈,从退出单词的itr开始
    		for (; itr!=vdict.end(); itr++)
    		{
    			int itrSize = (*itr).size();
    			string sCut = s.substr(i, itrSize);
    			if (!strcmp(sCut.c_str(), (*itr).c_str()))
    			{
    				iIndex.push_back(i);
    				iSet.push_back(itr);
    				i += itrSize;
    				break;
    			}
    		}
    		if (itr==vdict.end())//本轮没有找到,出栈
    		{
    			if (iIndex.size()==0)return false;
    			i = iIndex.back();
    			iIndex.pop_back();
    			popfg = true;
    		}
    	}//while
    	return true;
    }
};

直接用递归做了一下,思路跟上面一样,只不过采用了DFS,但是超时了

Last executed input:	"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", ["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]

代码如下:

class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
    	if (s.empty())return true;
    	bool bR = false;
    	for (unordered_set<string>::iterator vitr = dict.begin(); vitr != dict.end(); vitr++)
    	{
    		if (s.substr(0, (*vitr).size())==*vitr)
    		{
    			bR = wordBreak(s.substr((*vitr).size()), dict);
    		}
    		if (bR)return true; 
    	}
    	return false;
    }
};







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值