文章目录
- 广度优先搜索
- 力扣429-----N叉树的层序遍历
- 力扣994-----腐烂的橘子
- 力扣127 -------单词接龙
- 力扣725------打开转盘锁
广度优先搜索
需要借助 队列 来解决问题
例如二叉树的层序遍历 :
1, 将根节点入队
2, 队列出队的时候, 将该节点的左右子树节点入队, 然后循环操作。 这就是广度优先搜索。
力扣429-----N叉树的层序遍历
力扣429
class Solution {
public:
vector<vector<int>> levelOrder(Node* root)
{
if (root == nullptr)
return vector<vector<int>>();
vector<vector<int>> vv;
queue<Node*> q;
q.push(root);
while (!q.empty())
{
vector<int> v;
int sz = q.size();
while (sz--)
{
Node* node = q.front();
q.pop();
v.push_back(node->val);
for (auto e : node->children)
{
q.push(e);
}
}
vv.push_back(v);
}
return vv;
}
};
力扣994-----腐烂的橘子
力扣题994
1,解题思路 : BFS。
2,把第一次腐烂的橘子入队,(注意:这一次腐烂的橘子不计次数, 所以step不用计步数),然后取出每一个橘子,
向四周渲染(腐烂), 如果四周是好的橘子,就要将该位置的橘子改为2, 然后加入队列中。
然后循环上述的步骤就可以
int arr[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
class Solution {
public:
int orangesRotting(vector<vector<int>>& grid)
{
//1,找到一个腐烂的橘子
queue<pair<int,int>> q;
bool flag = false;
for(int i = 0; i < grid.size(); i++)
{
for(int j = 0; j < grid[0].size(); j++)
{
if(grid[i][j] == 2)
{
q.push({i, j});
}
if(grid[i][j] == 1)
{
flag = true;
}
}
}
if(flag == false)
return 0;
int step = 0;
while(!q.empty())
{
int sz = q.size();
while(sz--)
{
auto front = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int newx = arr[i][0] + front.first;
int newy = arr[i][1] + front.second;
if(newx < 0 || newx >= grid.size()
|| newy < 0 || newy >= grid[0].size())
continue;
if(grid[newx][newy] == 1)
{
grid[newx][newy] = 2;
q.push({newx, newy});
}
}
}
step++;
}
for(int i = 0; i < grid.size(); i++)
{
for(int j = 0; j < grid[0].size(); j++)
{
if(grid[i][j] == 1)
{
return -1;
}
}
}
return step - 1;
}
};
力扣127 -------单词接龙
力扣127
首先,将beginword入队。
然后 将beginword转换后的全部字符
判断是不是在字典wordlist中,如果在就可以入队,
但是wordlist中的字符串只能用一次, 否则会无脑循环。
然后将一次性入队字符串再进行上次的循环操作就可以
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList)
{
unordered_map<string, bool> m; //标识字符串是否用过了
for(auto& e : wordList)
m[e] = true;
if(m.find(endWord) == m.end())
return 0;
int step = 0;
queue<string> q;
q.push(beginWord);
while(!q.empty())
{
int sz = q.size();
step++;
while(sz--)
{
string str = q.front();
q.pop();
if(str == endWord)
return step;
for(int i = 0; i < str.size(); i++)
{
string s = str;
for(char ch = 'a'; ch <= 'z'; ch++)
{
s[i] = ch;
if(m[s] == true)
{
q.push(s);
m[s] = false;
}
}
}
}
}
return 0;
}
};
类似的题目:
力扣433
class Solution {
public:
int minMutation(string startGene, string endGene, vector<string>& bank)
{
unordered_map<string, bool> m;
for(auto& e : bank)
m[e] = true;
if(m.find(endGene) == m.end())
return -1;
int step = 0;
queue<string> q;
q.push(startGene);
string gene = "ACGT";
while(!q.empty())
{
int sz = q.size();
step++;
while(sz--)
{
string str = q.front();
q.pop();
if(str == endGene)
return step - 1;
for(int i = 0; i < str.size(); i++)
{
string s = str;
for(int j = 0; j < gene.size(); j++)
{
s[i] = gene[j];
if(m[s] == true)
{
q.push(s);
m[s] = false;
}
}
}
}
}
return -1;
}
};
力扣725------打开转盘锁
力扣725
解题思路非常清晰 : BFS
但是要用一个set 来标记这个字符串是否用过, 用过了就不能用了。
循环:
1, 取出队列中的一个元素。
2, 将每个元素的旋转的所有可能性全部入队 (不能出现在死亡数字里面)
class Solution {
public:
int openLock(vector<string>& deadends, string target)
{
unordered_map<string, bool> m;
set<string> _set;
for(auto& e : deadends)
m[e] = true;
if(m["0000"] == true || m[target] == true)
return -1;
queue<string> q;
q.push("0000");
int step = 0;
while(!q.empty())
{
int sz = q.size();
step++;
while(sz--)
{
string str = q.front();
q.pop();
if(str == target)
return step - 1;
for(int i = 0; i < 4; i++)
{
string s1 = str;
if(s1[i] == '9')
s1[i] = '0';
else
s1[i]++;
string s2 = str;
if(s2[i] == '0')
s2[i] = '9';
else
s2[i]--;
if(m[s1] != true && _set.find(s1) == _set.end())
{
q.push(s1);
_set.insert(s1);
}
if(m[s2] != true && _set.find(s2) == _set.end())
{
q.push(s2);
_set.insert(s2);
}
}
}
}
return -1;
}
};