1. 程式人生 > 其它 >leetcode(c++)(BFS)

leetcode(c++)(BFS)

#include <iostream>
#include <sstream>
#include <queue>
#include <string>
#include <unordered_set>
#include <unordered_map>
using namespace std;

struct TreeNode
{
    TreeNode(int v):val(v){}
    int val = 0;
    TreeNode* left = nullptr;
    TreeNode* right = nullptr;
};

void print(TreeNode* root) { if(nullptr == root)return ; cout << root->val << endl; print(root->left); print(root->right); return; } int minDepth(TreeNode* root) { if(nullptr == root)return 0; queue<TreeNode*>q; int depth = 1; q.push(root);
while(!q.empty()) { int size = q.size(); for(int i = 0; i < size; ++i) { TreeNode* cur = q.front(); q.pop(); if(cur->left == nullptr && cur->right == nullptr)return depth; if(cur->left)q.push(cur->left);
if(cur->right)q.push(cur->right); } ++depth; } return depth; } int minDepth_r(TreeNode* root) { if(nullptr == root)return 0; if(root->left == nullptr)return minDepth_r(root->right) + 1; if(root->right == nullptr)return minDepth_r(root->left) + 1; return min(minDepth_r(root->left),minDepth_r(root->right)) + 1; } vector<vector<int>>levelOrder(TreeNode* root) { vector<vector<int>>res; queue<TreeNode*>q; if(root == nullptr)return {}; q.push(root); while(!q.empty()) { vector<int>v; int size = q.size(); for(int i = 0; i < size; ++i) { TreeNode* cur = q.front(); q.pop(); v.emplace_back(cur->val); if(cur->left)q.push(cur->left); if(cur->right)q.push(cur->right); } res.emplace_back(v); } return res; } void dfs(TreeNode* root, vector<vector<int>>& res, int height) { if(nullptr == root)return; vector<int>t; if(height >= res.size())res.emplace_back(t); res[height].emplace_back(root->val); if(root->left)dfs(root->left,res,height + 1); if(root->right)dfs(root->right,res,height + 1); return ; } vector<vector<int>>levelOrderDFS(TreeNode* root) { vector<vector<int>>res; if(nullptr == root) return {}; dfs(root,res,0); return res; } void print(const vector<vector<int>>&nums) { for(auto num : nums) { for(auto n : num) { cout << n << " "; } cout << endl; } } int ladderLength(string beginWord,string endWord, const vector<string>& wordList) { unordered_set<string>set; for(auto word : wordList) { set.insert(word); } queue<string>q; q.push(beginWord); int n = beginWord.size(),step = 1; while(!q.empty()) { int size = q.size(); for(int i = 0; i < size; ++i) { string cur = q.front(); q.pop(); if(cur == endWord)return step; for(int j = 0; j < n; ++j) { for(char c = 'a'; c <= 'z'; ++c) { string next = cur; next[j] = c; if(set.count(next)) { if(next == endWord)return step + 1; set.erase(next); q.push(next); } } } } ++step; } return 0; } int ladderLength_BFS(string begWord, string endWord, const vector<string>& wordList) { unordered_set<string>begSet,endSet,visitedSet,wordSet; for(string str: wordList) { wordSet.insert(str); } if(!wordSet.count(endWord))return 0; int step = 1, n = begWord.size(); begSet.insert(begWord); endSet.insert(endWord); while(!begSet.empty() && !endSet.empty()) { unordered_set<string>nextSet; for(string str:begSet) { for(int i = 0; i < n; ++i) { for(char c = 'a'; c <= 'z'; ++c) { char pre = str[i]; string next = str; next[i] = c; if(endSet.count(next))return step + 1; visitedSet.insert(next); if(wordSet.count(next)) { nextSet.insert(next); } next[i] = pre; } } } if(endSet.size() < nextSet.size()) { begSet = endSet; endSet = nextSet; } else { begSet = nextSet; } ++step; } return 0; } vector<vector<int>>dirs{{0,1},{0,-1},{-1,0},{1,0}}; bool hasPath(const vector<vector<int>>&maze, const vector<int>& start, const vector<int>& des) { int m = maze.size(), n = maze[0].size(); vector<vector<bool>>visited(m,vector<bool>(n,false)); queue<vector<int>>q; q.push(start); while(!q.empty()) { auto cur = q.front(); q.pop(); if(cur[0] == des[0] && cur[1] == des[1])return true; for(auto dir:dirs) { int x = dir[0] + cur[0], y = dir[1] + cur[1]; while(x >= 0 && y >= 0 && x < m && y < n && maze[x][y] == 0) { x += dir[0]; y += dir[1]; } x -= dir[0]; y -= dir[1]; if(!visited[x][y]) { q.push({x,y}); visited[x][y] = true; } } } return false; } void dijlstra(const vector<vector<int>>& maze, const vector<int>&start,vector<vector<int>>&distance) { priority_queue<vector<int>>q; q.push({start[0],start[1],0}); while(!q.empty()) { auto cur = q.top(); q.pop(); for(auto dir:dirs) { int x = cur[0] + dir[0]; int y = cur[1] + dir[1]; int cnt = 0; while(x >= 0 && y >= 0 && x < maze.size() && y < maze[0].size() && maze[x][y]== 0) { x += dir[0]; y += dir[1]; ++cnt; } x -= dir[0]; y -= dir[1]; if(distance[cur[0]][cur[1]]+cnt < distance[x][y]) { distance[x][y] = distance[cur[0]][cur[1]]+cnt; q.push({x,y,distance[x][y]}); } } } } int shortestDistance(const vector<vector<int>>&maze,const vector<int>&start, const vector<int>& end) { int m = maze.size(), n = maze[0].size(); vector<vector<int>>distance(m,vector<int>(n,INT_MAX)); distance[start[0]][start[1]] = 0; dijlstra(maze,start,distance); return distance[end[0]][end[1]] == INTMAX_MAX ? -1 : distance[end[0]][end[1]]; } bool canFinish(int numCourses,const vector<vector<int>>& prerequists) { unordered_map<int,vector<int>>map; vector<int>indegree(numCourses); for(int i = 0; i < prerequists.size(); ++i) { int end = prerequists[i][0],start = prerequists[i][1]; map[start].emplace_back(end); ++indegree[end]; } queue<int>q; for(int i = 0; i < indegree.size(); ++i) { if(indegree[i] == 0) { q.push(i); } } int cnt = 0; while(!q.empty()) { int cur = q.front(); q.pop(); ++cnt; if(map.find(cur)!=map.end()) { for(int num : map.at(cur)) { if(--indegree[num] == 0)q.push(num); } } } return cnt == numCourses; } int openLock(vector<string>& deadends, string target) { if (target == "0000") { return 0; } unordered_set<string> dead(deadends.begin(), deadends.end()); if (dead.count("0000")) { return -1; } auto num_prev = [](char x) -> char { return (x == '0' ? '9' : x - 1); }; auto num_succ = [](char x) -> char { return (x == '9' ? '0' : x + 1); }; // 列舉 status 通過一次旋轉得到的數字 auto get = [&](string& status) -> vector<string> { vector<string> ret; for (int i = 0; i < 4; ++i) { char num = status[i]; status[i] = num_prev(num); ret.push_back(status); status[i] = num_succ(num); ret.push_back(status); status[i] = num; } return ret; }; queue<pair<string, int>> q; q.emplace("0000", 0); unordered_set<string> seen = {"0000"}; while (!q.empty()) { auto cur = q.front(); string status = cur.first; int step = cur.second; q.pop(); for (auto&& next_status: get(status)) { if (!seen.count(next_status) && !dead.count(next_status)) { if (next_status == target) { return step + 1; } q.emplace(next_status, step + 1); seen.insert(move(next_status)); } } } return -1; } int main() { //LeetCode111 TreeNode t1(3); TreeNode t2(9); TreeNode t3(20); TreeNode t4(15); TreeNode t5(7); t1.left = &t2; t1.right = &t3; t3.left = &t4; t3.right = &t5; // print(&t1); cout << minDepth(&t1) << endl; cout << minDepth_r(&t1) << endl; //LeetCode102 print(levelOrder(&t1)); print(levelOrderDFS(&t1)); //LeetCode127 string begWord = "hit", endWord = "cog"; vector<string>WordList{"hot","dot","dog","lot","log","cog"}; cout << ladderLength(begWord,endWord,WordList) << endl; cout << ladderLength_BFS(begWord,endWord,WordList) << endl; //LeetCode752 vector<string>deadends{"0201","0101","0102","1212","2002"}; string target = "0202"; cout << openLock(deadends,target) << endl; //LeetCode490 vector<vector<int>>maze{{0,0,1,0,0},{0,0,0,0,0},{0,0,0,1,0},{1,1,0,1,1},{0,0,0,0,0}}; vector<int>start{0,4},destination{4,4}; cout << hasPath(maze,start,destination) << endl; //LeetCode505 cout << shortestDistance(maze,start,destination) <<endl; //LeetCode207 int numCourses = 2; vector<vector<int>>prerequistes{{1,0},{0,1}}; cout << canFinish(numCourses,prerequistes) << endl; return 0; }