广度优先搜索,暴力搜索
广度优先搜索的时候要清晰的知道我们在遍历什么,加入队列就是我们的遍历的目标,遍历的时候注意什么时候是结束条件,什么条件是将下个遍历的元素加入队列,存在重复遍历的位置的时候,需要一个是否访问过的变量进行记录访问的状态,不然会重复遍历,剪枝能够大大提高时间。
模板不难,难的是知道我们在遍历什么,DFS常用于最小路径,把一些遍历的node当作无向图里的节点。
难度中等415
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:
- 拆分时可以重复使用字典中的单词。
- 你可以假设字典中没有重复的单词。
示例 1:
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。
示例 2:
输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
注意你可以重复使用字典中的单词。
示例 3:
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false
- 暴力搜索的时候需要进行剪枝,否则时间复杂度过不了,我做的时候,没有考虑到剪枝,导致超时
#include <queue>
#include <set>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
class Solution {
public:
bool WordDFS(int pos, string s, vector<string>& wordDict, vector<int> &visited)
{
if (pos == s.length()) {
return true;
}
// 产生剪枝,不然会过多的重复
if (visited[pos] == 1) {
return true;
} else if (visited[pos] == 2) {
return false;
}
// 存在先找小的
for (int end = s.length() - 1; end >= pos; end--) {
if (find(wordDict.begin(), wordDict.end(), s.substr(pos, end - pos + 1)) != wordDict.end() &&
WordDFS(end + 1, s, wordDict, visited)) {
visited[pos] = 1;
return true;
}
}
visited[pos] = 2;
return false;
}
bool wordBreak(string s, vector<string>& wordDict) {
vector<int> visited(s.length(), 0);
return WordDFS(0, s, wordDict, visited);
}
};
2 bfs
class Solution {
public:
bool WordBFS(string s, vector<string>& wordDict)
{
// 转换成set方便查询是否存在
set<string> wordDic(wordDict.begin(), wordDict.end());
// 广度优先算法必有队列,进行遍历的结构体
queue<int> q;
q.push(0);
// 剪枝,对已经访问过的位置进行记录,产生剪枝
set<int> visited;
while (!q.empty()) {
int size = q.size();
// 模板
for (int index = 0; index < size; index++) {
int tmp = q.front();
q.pop();
// 差异性处理,对从队列的访问的地址开始向后遍历字符串
for (int end = tmp + 1; end <= s.length(); end++) {
// 不存在的时候遍历下一个子字符串
if (wordDic.count(s.substr(tmp, end - tmp)) == 0) {
continue;
}
// 结束条件是遍历到最后并且都存在
if (end == s.length()) {
return true;
}
// 剪枝,从找到的这个字符串的下一个位置开始找
if (visited.count(end) == 0) {
visited.insert(end);
q.push(end);
}
}
}
}
return false;
}
bool wordBreak(string s, vector<string>& wordDict) {
if (s.length() == 0 || wordDict.empty()) {
return false;
}
return WordBFS(s, wordDict);
}
};