//双向 BFS
class Solution
{
public:
int openLock(vector<string>& deadends, string target)
{
// BFS 模板,打印所有可能密码
unordered_set <string> q1, q2;
unordered_set <string> dead;
unordered_set <string> version;
for (string str : deadends) dead.insert(str);
//把初始密码添加到队列中
q1.insert("0000");
q2.insert(target);
int depth = 0;
while (!q1.empty() && !q2.empty())
{
//该条件语句是双向 BFS 的优化
if (q1.size() > q2.size())
{
unordered_set<string> temp1 = q1;
q1 = q2;
q2 = temp1;
}
unordered_set <string> temp;
for ( string cur : q1 )
{
//判断是否是正确密码
if (dead.find(cur) != dead.end()) continue;
//判断两个容器是否有交集,若有交集则结束——关键之处
if (q2.find(cur) != q2.end()) return depth;
version.insert(cur);
for (int j = 0; j < 4; j++)
{
//转动一次密码并添加到队列中
string up = plusone(cur, j);
//判断是否是回头路
if (version.find(up) == version.end())
temp.insert(up);
string down = minnusone(cur, j);
if (version.find(down) == version.end())
temp.insert(down);
}
}
depth++;
// temp 相当于 q1
// 在这里交换 q1 和 q2 ,下一轮 while 会扩散 q2
q1 = q2;
q2 = temp;
}
return -1;
}
private:
string plusone(string s, int i)
{
string ch = s;
if (ch[i] == '9') ch[i] = '0';
else ch[i] += 1;
return ch;
}
string minnusone(string s, int i)
{
string ch = s;
if (ch[i] == '0') ch[i] = '9';
else ch[i] -= 1;
return ch;
}
};
003 双向 BFS 实现解开密码锁的最少次数[C++]
最新推荐文章于 2024-07-20 22:49:13 发布