BFS
- 计算在网格中从原点到特定点的最短路径长度 1091. Shortest Path in Binary Matrix(Medium)
- 组成整数的最小平方数数量 279. Perfect Squares(Medium)
- 最短单词路径127. Word Ladder(hard)
总结:BFS通常比较适用于寻找最短路径,这三道题都是采用的类似层次遍历的写法,这样就不用把路径长度信息存入节点信息中。
计算在网格中从原点到特定点的最短路径长度
注意点:
- 不仅要检查出发点的有效性还要检查终止点的有效性
- 路径长度计数变量+1的时机,也就是什么时候让路径长度+1
- 记录visited是必须的
typedef pair<int,int> P;
class Solution {
public:
int shortestPathBinaryMatrix(vector<vector<int>>& grid) {
int n = grid.size();
if(grid[0][0] == 1 || grid[n-1][n-1] == 1)
return -1;
int ans = 1;
int dx[8] = {0,0,1,1,1,-1,-1,-1};
int dy[8] = {1,-1,1,0,-1,1,0,-1};
queue<P> q;
q.push({0, 0});
grid[0][0] = 2;
while(!q.empty()){
int size = q.size();
while(size--){
P u = q.front();
q.pop();
if(u.first == n-1 && u.second == n-1)
return ans;
for(int i = 0;i < 8; i++){
int nx = u.first + dx[i];
int ny = u.second + dy[i];
if(nx >= 0 && nx < n && ny >= 0 && ny < n && grid[nx][ny] == 0 && grid[nx][ny] != 2){
grid[nx][ny] = 2;
q.push({nx, ny});
}
}
}
ans += 1;
}
return -1;
}
};
组成整数的最小平方数数量
本题最直观的解法是动态规划
class Solution {
public:
int numSquares(int n) {
int dp[10005];
dp[0] = 0;
for(int i = 1;i <= n; i++){
dp[i] = 100005;
for(int j = sqrt(i);j >= 1; j--)
dp[i] = min(dp[i], dp[i-j*j] + 1);
}
return dp[n];
}
};
将1…n当作一个图中的节点,如果相差一个平方数则连一条边,这样就把平方数加和到n转换到了n到0的边的条数,用BFS求解
class Solution {
public:
int numSquares(int n){
/*
思路:1...n都是图中的节点,如果相差一个平方数则连一条边,这样就把平方数加和到n转换到了n到0的边的条数
*/
int mark[10005];
memset(mark, 0, sizeof(mark));
queue<int> q;
q.push(n);
mark[n] = 1;
int ans = 0;
while(!q.empty()){
int size = q.size();
ans += 1;
while(size--){
int u = q.front();
q.pop();
for(int v = sqrt(u);v >= 1; v--){
if(v*v == u)
return ans;
else if(v*v < u && mark[u-v*v] == 0){
q.push(u - v*v);
mark[u-v*v] = 1;
}
}
}
}
return ans;
}
};
最短单词路径
class Solution {
public:
bool compare(string& s1, string& s2){
if(s1.size() != s2.size())
return false;
int flag = 0;
for(int i = 0;i < s1.size(); i++)
if(s1[i] != s2[i]){
if(flag == 0)
flag = 1;
else if(flag == 1)
return false;
}
return true;
}
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
int source, target = -1;
int n = wordList.size();
vector<int> G[5005];
int visited[5005];
memset(visited, 0, sizeof(visited));
wordList.push_back(beginWord);
source = n;
for(int i = 0;i <= n; i++){
for(int j = i+1; j <= n; j++){
if(compare(wordList[i], wordList[j])){
G[i].push_back(j);
G[j].push_back(i);
}
}
if(wordList[i] == endWord)
target = i;
}
if(target == -1)
return 0;
queue<int> q;
q.push(source);
visited[source] = 1;
int ans = 0;
while(!q.empty()){
int size = q.size();
ans += 1;
while(size--){
int u = q.front();
q.pop();
visited[u] = 1;
if(u == target)
return ans;
for(int i = 0;i < G[u].size(); i++){
int v = G[u][i];
if(visited[v] == 0)
q.push(v);
}
}
}
return 0;
}
};