【C++刷题】优选算法——BFS第二辑

最短路问题解决
边权为 1 的最短路问题

  1. 迷宫中离入口最近的出口
    在这里插入图片描述
class Solution {
	vector<vector<bool>> mark;
	queue<pair<int, int>> q;
	int step = 0;
	unordered_multimap<int, int> direction = {
	    {0, 1},
	    {0, -1},
	    {1, 0},
	    {-1, 0},
	};
public:
    int bfs(vector<vector<char>>& maze) {
        while (!q.empty()) {
            int size = q.size();
            while (size--) {
                auto pos = q.front();
                q.pop();
                for (auto& e : direction) {
                    int x = pos.first + e.first, y = pos.second + e.second;
                    if ((x >= 0 && x < maze.size())
                    && (y >= 0 && y < maze[0].size())
                    && (maze[x][y] == '.')
                    && (mark[x][y] == false)) {
                        if (x == 0 || x == maze.size() - 1
                        || y == 0 || y == maze[0].size() - 1) {
                            return step + 1;
                        }
                        mark[x][y] = true;
                        q.push({x, y});
                    }
                }
            }
            ++step;
        }
        return -1;
    }
    int nearestExit(vector<vector<char>>& maze, vector<int>& entrance) {
        int m = maze.size(), n = maze[0].size();
        mark = vector<vector<bool>>(m, vector<bool>(n, false));

        q.push({entrance[0], entrance[1]});
        mark[entrance[0]][entrance[1]] = true;
        return bfs(maze);
    }
};
  1. 最小基因变化
    在这里插入图片描述
class Solution {
	string _endGene;
	unordered_set<string> _bank;
	queue<string> _q;
	unordered_set<string> _mark;
	int _step = 0;
	vector<char> _gene = { 'A', 'C', 'G', 'T' };
public:
    int bfs() {
        while (!_q.empty()) {
            int size = _q.size();
            while (size--) {
                string front = _q.front();
                _q.pop();
                for (int i = 0; i < 8; ++i) {
                    for (char c : _gene) {
                        char tmp = front[i];
                        front[i] = c;
                        if (front == _endGene) {
                            return _step + 1;
                        }
                        if (!_mark.count(front) && _bank.count(front)) {
                            _q.push(front);
                            _mark.insert(front);
                        }
                        front[i] = tmp;
                    }
                }
            }
            ++_step;
        }
        return -1;
    }
    int minMutation(string startGene, string endGene, vector<string>& bank) {
        if (startGene == endGene) return 0;

        _endGene = endGene;
        for (string& e : bank) {
            _bank.insert(e);
        }

        if (!_bank.count(_endGene)) return -1;

        _q.push(startGene);
        _mark.insert(startGene);
        return bfs();
    }
};
  1. 单词接龙
    在这里插入图片描述
class Solution {
	int _length;
	string _endWord;
	unordered_set<string> _wordList;
	queue<string> _q;
	unordered_set<string> _mark;
	int _step = 1;
public:
    int bfs() {
        while (!_q.empty()) {
            int size = _q.size();
            while (size--) {
                string front = _q.front();
                _q.pop();
                for (int i = 0; i < _length; ++i) {
                    for (int c = 'a'; c <= 'z'; ++c) {
                        char tmp = front[i];
                        front[i] = c;
                        if (front == _endWord) {
                            return _step + 1;
                        }
                        if (!_mark.count(front) && _wordList.count(front)) {
                            _q.push(front);
                            _mark.insert(front);
                        }
                        front[i] = tmp;
                    }
                }
            }
            ++_step;
        }
        return 0;
    }
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        _length = beginWord.size();
        _endWord = endWord;
        for (string& e : wordList) {
            _wordList.insert(e);
        }
        if (!_wordList.count(_endWord)) return 0;

        _q.push(beginWord);
        _mark.insert(beginWord);
        return bfs();
    }
};
  1. 为高尔夫比赛砍树
    在这里插入图片描述
class Solution {
    int _m, _n;
    map<int, pair<int, int>> _path;
    unordered_multimap<int, int> _direction = {
        {0, 1},
        {0, -1},
        {1, 0},
        {-1, 0},
    };
public:
    int bfs(vector<vector<int>>& forest, const pair<int, int>& start, const pair<int, int>& end) {
        if (start.first == end.first && start.second == end.second) return 0;
        vector<vector<bool>> mark = vector<vector<bool>>(_m, vector<bool>(_n, false));
        queue<pair<int, int>> q;
        mark[start.first][start.second] = true;
        q.push(start);
        int step = 0;
        while (!q.empty()) {
            int size = q.size();
            while (size--) {
                auto front = q.front();
                q.pop();
                for (auto& e : _direction) {
                    int x = front.first + e.first, y = front.second + e.second;
                    if (x >= 0 && x < forest.size()
                        && y >= 0 && y < forest[0].size()
                        && !mark[x][y]
                        && forest[x][y]) {
                        if (x == end.first && y == end.second) return step + 1;
                        mark[x][y] = true;
                        q.push({ x, y });
                    }
                }
            }
            ++step;
        }
        return -1;
    }

    int cutOffTree(vector<vector<int>>& forest) {
        if (forest[0][0] == 0) return -1;

        _m = forest.size(), _n = forest[0].size();
        for (int i = 0; i < _m; ++i) {
            for (int j = 0; j < _n; ++j) {
                if (forest[i][j] > 1) _path[forest[i][j]] = {i, j};
            }
        }

        int ret = 0;
        pair<int, int> start = {0, 0};
        for (auto& end : _path) {
            int step = bfs(forest, start, end.second);
            if (step == -1) return -1;
            else ret += step;
            start = end.second;
        }
        return ret;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿阿阿顺Yaya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值