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;
}

 

posted @ 2022-05-08 12:02  fourmii  阅读(27)  评论(0编辑  收藏  举报