图论

图论

200.岛屿数量

image

//连通块问题,计算连通块个数,用dfs前后左右搜
class Solution {
public:
void dfs(int x,int y,vector<vector<char>>& grid){
    int h=grid.size();//行数
    int l=grid[0].size();//列数
    grid[x][y]='0';
    //只有下一步是1 才能搜
    if(x-1>=0&&grid[x-1][y]=='1') dfs(x-1,y,grid);//向上搜索
    if(x+1<h&&grid[x+1][y]=='1') dfs(x+1,y,grid);//向下搜索
    if(y-1>=0&&grid[x][y-1]=='1') dfs(x,y-1,grid);
    if(y+1<l&&grid[x][y+1]=='1') dfs(x,y+1,grid);

}
    int numIslands(vector<vector<char>>& grid) {
        int r=grid.size();//行数
        if(r==0)return 0;
        int c=grid[0].size();//列数
        int ans=0;
        for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                if(grid[i][j]=='1'){
                    ans++;
                    dfs(i,j,grid);
                }
            }
        }
        return ans;
    }
};

994.腐烂的橘子

image

class Solution {
    // 本题求最短时间->最小值需要用宽度优先遍历
private:
    int dx[4] = {-1, 1, 0, 0}; // 行,上下左右
    int dy[4] = {0, 0, -1, 1}; // 列
public:
    int orangesRotting(vector<vector<int>>& grid) {
        queue<pair<int, int>> q;
        int time = 0;
        int fresh = 0;
        int h = grid.size();    // 行
        int l = grid[0].size(); // 列
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < l; j++) {
                if (grid[i][j] == 2) {
                    q.push({i, j});
                } else if (grid[i][j] == 1) {
                    fresh++;
                }
            }
        }
        while (!q.empty()) { // 腐烂橘子队列
            int n = q.size();
            bool f=false;
            // 对每一个当前队列里面腐烂的橘子进行上下左右搜(不会有重复)
            for (int i = 0; i < n; i++) {
                auto orange=q.front();
                q.pop();
                for(int j=0;j<4;j++){
                    int x=orange.first+dx[j];
                    int y=orange.second+dy[j];
                    if(x>=0&&x<h&&y>=0&&y<l&&grid[x][y]==1){
                        grid[x][y]=2;
                        q.push({x,y});
                        fresh--;
                        f=true;
                    }
                }

            }
            if(f==true){
                time++;
            }
        }

        if (fresh != 0) {
            return -1;
        } else {
            return time;
        }
    }
};

207.课程表

考点:拓扑排序

思路:把入度为0的点放入队列,然后依次弹出而且会修改与他相连的点让这些点入度-1,最终如果所有的入度都为0则可以完成所有课程学习

存储用邻接表

image

class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
       

        // 每个节点的入度
        vector<int> indegrees(numCourses, 0);

        // 邻接表
        vector<vector<int>> graph(numCourses);

        // 填充初始邻接表和入度值
        for (const auto& prerequisite : prerequisites) {
            // 添加从课程 prerequisite[1] 到课程 prerequisite[0] 的有向边
            graph[prerequisite[1]].push_back(prerequisite[0]);
            // 课程 prerequisite[0] 的入度加1
            indegrees[prerequisite[0]]++;
        }

        // 使用队列进行拓扑排序
        queue<int> q;

        // 首先找到所有头部节点(入度为 0 的节点)
        for (int i = 0; i < numCourses; i++) {
            if (indegrees[i] == 0) {
                q.push(i);
            }
        }

        // 执行拓扑排序
        while (!q.empty()) {
            // 当前节点
            int cur = q.front();
            q.pop();

            // 获取当前节点的后继节点
            vector<int>& targets = graph[cur];

            // 遍历所有的后继节点,减少他们的入度
            for (int next : targets) {
                // 减少入度
                indegrees[next]--;
                // 如果后继节点的入度为0,加入队列
                if (indegrees[next] == 0) {
                    q.push(next);
                }
            }
        }

        // 检查所有节点的入度是否都为0
        // 若存在入度不为0的节点,说明图中存在环,无法完成所有课程
        for (int degree : indegrees) {
            if (degree != 0) {
                return false;
            }
        }

        return true;
    }
};

207.课程表

image

class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        vector<int> indegrees(numCourses, 0);     // 入度
        vector<vector<int>> ljb(numCourses);      // 邻接表
        for (auto prerequisite : prerequisites) { // 取出每个一维的数组b->a
            indegrees[prerequisite[0]]++; // prerequisite的第一维是a,a的入度+1
            ljb[prerequisite[1]].push_back(
                prerequisite[0]); // 邻接表中添加b->a的这一条边
        }
        queue<int> d;
        for (int i = 0; i < numCourses; i++) {
            if (indegrees[i] == 0) { // 入度为0放入队列中
                d.push(i);
            }
        }
        while (!d.empty()) {
            int y = d.front();
            d.pop();
            for (auto i : ljb[y]) {//与y相邻的所有点去修改。
                indegrees[i]--;
                if (indegrees[i] == 0) {
                    d.push(i);
                }
            }
        }
        for (auto i : indegrees) {
            if (i != 0) {
                return false;
            }
        }
        return true;
    }
};

208.实现Trie(前缀树)

image

 

class Trie {
private:
    vector<Trie*> children;
    bool isEnd;

    Trie* searchPrefix(string prefix) {
        Trie* node = this;
        for (char ch : prefix) {
            ch -= 'a';
            if (node->children[ch] == nullptr) {
                return nullptr;
            }
            node = node->children[ch];
        }
        return node;
    }

public:
    Trie() : children(26), isEnd(false) {}

    void insert(string word) {
        Trie* node = this;
        for (char ch : word) {
            ch -= 'a';
            if (node->children[ch] == nullptr) {
                node->children[ch] = new Trie();
            }
            node = node->children[ch];
        }
        node->isEnd = true;
    }

    bool search(string word) {
        Trie* node = this->searchPrefix(word);
        return node != nullptr && node->isEnd;
    }

    bool startsWith(string prefix) {
        return this->searchPrefix(prefix) != nullptr;
    }
};



/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */

 

posted @ 2025-12-20 13:09  Annaprincess  阅读(3)  评论(0)    收藏  举报